Define new event-channel and physdev hypercalls with a more extensible
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Sun, 30 Apr 2006 08:16:15 +0000 (09:16 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Sun, 30 Apr 2006 08:16:15 +0000 (09:16 +0100)
interface (the legacy hypercalls would break if subcommands with large
argument structures were added, as it would grow the size of the
union of all argument structures).

Also, based on a patch from Kevin Tian, add a new physdev op to
signal EOI for a particular irq.

Signed-off-by: Keir Fraser <keir@xensource.com>
49 files changed:
linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c
linux-2.6-xen-sparse/arch/i386/kernel/ioport-xen.c
linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c
linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c
linux-2.6-xen-sparse/arch/ia64/Kconfig
linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c
linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c
linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c
linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c
linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c
linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c
linux-2.6-xen-sparse/drivers/xen/Kconfig
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
linux-2.6-xen-sparse/drivers/xen/blktap/interface.c
linux-2.6-xen-sparse/drivers/xen/core/evtchn.c
linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h
linux-2.6-xen-sparse/include/asm-ia64/hypercall.h
linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h
linux-2.6-xen-sparse/include/xen/evtchn.h
tools/libxc/xc_evtchn.c
xen/arch/ia64/vmx/vmx_hypercall.c
xen/arch/ia64/vmx/vmx_ivt.S
xen/arch/ia64/xen/hypercall.c
xen/arch/ia64/xen/irq.c
xen/arch/x86/Makefile
xen/arch/x86/compat.c [new file with mode: 0644]
xen/arch/x86/irq.c
xen/arch/x86/physdev.c
xen/arch/x86/x86_32/entry.S
xen/arch/x86/x86_64/entry.S
xen/common/event_channel.c
xen/include/acm/acm_hooks.h
xen/include/asm-ia64/hypercall.h
xen/include/asm-x86/hypercall.h
xen/include/public/event_channel.h
xen/include/public/physdev.h
xen/include/public/xen-compat.h
xen/include/public/xen.h
xen/include/xen/hypercall.h
xen/include/xen/irq.h

index cf0e62c5ffb49cd72367b570bf0e1511861ca88d..e7e1aa834a05d09df0094c0c23e08029c8ca51a2 100644 (file)
@@ -57,27 +57,25 @@ unsigned long io_apic_irqs;
 
 static inline unsigned int xen_io_apic_read(unsigned int apic, unsigned int reg)
 {
-       physdev_op_t op;
+       struct physdev_apic apic_op;
        int ret;
 
-       op.cmd = PHYSDEVOP_APIC_READ;
-       op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
-       op.u.apic_op.reg = reg;
-       ret = HYPERVISOR_physdev_op(&op);
+       apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
+       apic_op.reg = reg;
+       ret = HYPERVISOR_physdev_op(PHYSDEVOP_apic_read, &apic_op);
        if (ret)
                return ret;
-       return op.u.apic_op.value;
+       return apic_op.value;
 }
 
 static inline void xen_io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
 {
-       physdev_op_t op;
+       struct physdev_apic apic_op;
 
-       op.cmd = PHYSDEVOP_APIC_WRITE;
-       op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
-       op.u.apic_op.reg = reg;
-       op.u.apic_op.value = value;
-       HYPERVISOR_physdev_op(&op);
+       apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
+       apic_op.reg = reg;
+       apic_op.value = value;
+       HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op);
 }
 
 #define io_apic_read(a,r)    xen_io_apic_read(a,r)
@@ -1205,22 +1203,21 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mostly; /* = { FIRST_DEVICE_VECTOR , 0 }; *
 
 int assign_irq_vector(int irq)
 {
-       physdev_op_t op;
+       struct physdev_irq irq_op;
 
        BUG_ON(irq >= NR_IRQ_VECTORS);
        if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0)
                return IO_APIC_VECTOR(irq);
 
-       op.cmd = PHYSDEVOP_ASSIGN_VECTOR;
-       op.u.irq_op.irq = irq;
-       if (HYPERVISOR_physdev_op(&op))
+       irq_op.irq = irq;
+       if (HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op))
                return -ENOSPC;
 
-       vector_irq[op.u.irq_op.vector] = irq;
+       vector_irq[irq_op.vector] = irq;
        if (irq != AUTO_ASSIGN)
-               IO_APIC_VECTOR(irq) = op.u.irq_op.vector;
+               IO_APIC_VECTOR(irq) = irq_op.vector;
 
-       return op.u.irq_op.vector;
+       return irq_op.vector;
 }
 
 #ifndef CONFIG_XEN
index fe395b146c94e931f080fa36555b78e173f2ab6d..ee66fc288b68f76673a521bcabe6d797d5bd628e 100644 (file)
@@ -60,7 +60,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
 {
        struct thread_struct * t = &current->thread;
        unsigned long *bitmap;
-       physdev_op_t op;
+       struct physdev_set_iobitmap set_iobitmap;
 
        if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
                return -EINVAL;
@@ -80,10 +80,9 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
                memset(bitmap, 0xff, IO_BITMAP_BYTES);
                t->io_bitmap_ptr = bitmap;
 
-               op.cmd = PHYSDEVOP_SET_IOBITMAP;
-               op.u.set_iobitmap.bitmap   = (char *)bitmap;
-               op.u.set_iobitmap.nr_ports = IO_BITMAP_BITS;
-               HYPERVISOR_physdev_op(&op);
+               set_iobitmap.bitmap   = (char *)bitmap;
+               set_iobitmap.nr_ports = IO_BITMAP_BITS;
+               HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap);
        }
 
        set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
index 02f2835f5672d89c666591a189c7e7fd298b4f57..162ea42dd91d2e18da2ac5994a08efd90ac1a377 100644 (file)
@@ -297,9 +297,8 @@ void exit_thread(void)
 
        /* The process may have allocated an io port bitmap... nuke it. */
        if (unlikely(NULL != t->io_bitmap_ptr)) {
-               physdev_op_t op = { 0 };
-               op.cmd = PHYSDEVOP_SET_IOBITMAP;
-               HYPERVISOR_physdev_op(&op);
+               struct physdev_set_iobitmap set_iobitmap = { 0 };
+               HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap);
                kfree(t->io_bitmap_ptr);
                t->io_bitmap_ptr = NULL;
        }
@@ -521,7 +520,8 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas
 #ifndef CONFIG_X86_NO_TSS
        struct tss_struct *tss = &per_cpu(init_tss, cpu);
 #endif
-       physdev_op_t iopl_op, iobmp_op;
+       struct physdev_set_iopl iopl_op;
+       struct physdev_set_iobitmap iobmp_op;
        multicall_entry_t _mcl[8], *mcl = _mcl;
 
        /* XEN NOTE: FS/GS saved in switch_mm(), not here. */
@@ -568,23 +568,19 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas
 #undef C
 
        if (unlikely(prev->iopl != next->iopl)) {
-               iopl_op.cmd             = PHYSDEVOP_SET_IOPL;
-               iopl_op.u.set_iopl.iopl = (next->iopl == 0) ? 1 :
-                       (next->iopl >> 12) & 3;
+               iopl_op.iopl = (next->iopl == 0) ? 1 : (next->iopl >> 12) & 3;
                mcl->op      = __HYPERVISOR_physdev_op;
-               mcl->args[0] = (unsigned long)&iopl_op;
+               mcl->args[0] = PHYSDEVOP_set_iopl;
+               mcl->args[1] = (unsigned long)&iopl_op;
                mcl++;
        }
 
        if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) {
-               iobmp_op.cmd                     =
-                       PHYSDEVOP_SET_IOBITMAP;
-               iobmp_op.u.set_iobitmap.bitmap   =
-                       (char *)next->io_bitmap_ptr;
-               iobmp_op.u.set_iobitmap.nr_ports =
-                       next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
+               iobmp_op.bitmap   = (char *)next->io_bitmap_ptr;
+               iobmp_op.nr_ports = next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
                mcl->op      = __HYPERVISOR_physdev_op;
-               mcl->args[0] = (unsigned long)&iobmp_op;
+               mcl->args[0] = PHYSDEVOP_set_iobitmap;
+               mcl->args[1] = (unsigned long)&iobmp_op;
                mcl++;
        }
 
index 0921330bfeea20a4b044d2a75135606ab215bf50..6fbde82f486e9b12da8db6abc000e32ae4bff61a 100644 (file)
@@ -1630,7 +1630,7 @@ static void set_mca_bus(int x) { }
 void __init setup_arch(char **cmdline_p)
 {
        int i, j, k, fpp;
-       physdev_op_t op;
+       struct physdev_set_iopl set_iopl;
        unsigned long max_low_pfn;
 
        /* Force a quick death if the kernel panics (not domain 0). */
@@ -1815,9 +1815,8 @@ void __init setup_arch(char **cmdline_p)
        if (efi_enabled)
                efi_map_memmap();
 
-       op.cmd             = PHYSDEVOP_SET_IOPL;
-       op.u.set_iopl.iopl = 1;
-       HYPERVISOR_physdev_op(&op);
+       set_iopl.iopl = 1;
+       HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
 
 #ifdef CONFIG_X86_IO_APIC
        check_acpi_pci();       /* Checks more than just ACPI actually */
index 6bb58cb15fcc0801118ef352bc801716910732e2..13df89f457fe0ce52386225cbd2c459e1d4d994b 100644 (file)
@@ -106,7 +106,7 @@ config XEN_SYSFS
 config XEN_INTERFACE_VERSION
        hex
        depends on XEN
-       default 0x00030201
+       default 0x00030202
 
 config SCHED_NO_NO_OMIT_FRAME_POINTER
        bool
index 8fba804bbeeb7a21d0af5f67aaeae2adff7c8e91..2f955cb5ab3942f91a6ee4d796458a653fd533b6 100644 (file)
@@ -146,29 +146,27 @@ static LIST_HEAD(free_rte_list);
 #include <asm/hypervisor.h>
 static inline unsigned int xen_iosapic_read(char __iomem *iosapic, unsigned int reg)
 {
-       physdev_op_t op;
+       struct physdev_apic apic_op;
        int ret;
 
-       op.cmd = PHYSDEVOP_APIC_READ;
-       op.u.apic_op.apic_physbase = (unsigned long)iosapic -
+       apic_op.apic_physbase = (unsigned long)iosapic -
                                        __IA64_UNCACHED_OFFSET;
-       op.u.apic_op.reg = reg;
-       ret = HYPERVISOR_physdev_op(&op);
+       apic_op.reg = reg;
+       ret = HYPERVISOR_physdev_op(PHYSDEVOP_apic_read, &apic_op);
        if (ret)
                return ret;
-       return op.u.apic_op.value;
+       return apic_op.value;
 }
 
 static inline void xen_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
 {
-       physdev_op_t op;
+       struct physdev_apic apic_op;
 
-       op.cmd = PHYSDEVOP_APIC_WRITE;
-       op.u.apic_op.apic_physbase = (unsigned long)iosapic - 
+       apic_op.apic_physbase = (unsigned long)iosapic - 
                                        __IA64_UNCACHED_OFFSET;
-       op.u.apic_op.reg = reg;
-       op.u.apic_op.value = val;
-       HYPERVISOR_physdev_op(&op);
+       apic_op.reg = reg;
+       apic_op.value = val;
+       HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op);
 }
 
 static inline unsigned int iosapic_read(char __iomem *iosapic, unsigned int reg)
@@ -191,14 +189,13 @@ static inline void iosapic_write(char __iomem *iosapic, unsigned int reg, u32 va
 
 int xen_assign_irq_vector(int irq)
 {
-       physdev_op_t op;
+       struct physdev_irq irq_op;
 
-       op.cmd = PHYSDEVOP_ASSIGN_VECTOR;
-       op.u.irq_op.irq = irq;
-       if (HYPERVISOR_physdev_op(&op))
+       irq_op.irq = irq;
+       if (HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op))
                return -ENOSPC;
 
-       return op.u.irq_op.vector;
+       return irq_op.vector;
 }
 #endif /* XEN */
 
index fa753e512b5a43624276cc1c4d15eb51ca2c7069..1e7df722d065b7e868dffb9bd14fcd978bba8780 100644 (file)
@@ -61,9 +61,8 @@ void unmask_evtchn(int port)
 #if 0  // FIXME: diverged from x86 evtchn.c
        /* Slow path (hypercall) if this is a non-local port. */
        if (unlikely(cpu != cpu_from_evtchn(port))) {
-               evtchn_op_t op = { .cmd = EVTCHNOP_unmask,
-                                  .u.unmask.port = port };
-               (void)HYPERVISOR_event_channel_op(&op);
+               struct evtchn_unmask op = { .port = port };
+               (void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask, &op);
                return;
        }
 #endif
@@ -95,16 +94,16 @@ int bind_virq_to_irqhandler(
        const char *devname,
        void *dev_id)
 {
-    evtchn_op_t op;
+    struct evtchn_bind_virq bind_virq;
     int evtchn;
 
     spin_lock(&irq_mapping_update_lock);
 
-    op.cmd = EVTCHNOP_bind_virq;
-    op.u.bind_virq.virq = virq;
-    op.u.bind_virq.vcpu = cpu;
-    BUG_ON(HYPERVISOR_event_channel_op(&op) != 0 );
-    evtchn = op.u.bind_virq.port;
+    bind_virq.virq = virq;
+    bind_virq.vcpu = cpu;
+    if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq, &bind_virq) != 0)
+        BUG();
+    evtchn = bind_virq.port;
 
     if (!unbound_irq(evtchn)) {
         evtchn = -EINVAL;
@@ -158,7 +157,7 @@ int bind_ipi_to_irqhandler(
 
 void unbind_from_irqhandler(unsigned int irq, void *dev_id)
 {
-    evtchn_op_t op;
+    struct evtchn_close close;
     int evtchn = evtchn_from_irq(irq);
 
     spin_lock(&irq_mapping_update_lock);
@@ -166,9 +165,9 @@ void unbind_from_irqhandler(unsigned int irq, void *dev_id)
     if (unbound_irq(irq))
         goto out;
 
-    op.cmd = EVTCHNOP_close;
-    op.u.close.port = evtchn;
-    BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+    close.port = evtchn;
+    if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
+        BUG();
 
     switch (type_from_irq(irq)) {
        case IRQT_VIRQ:
index d71120093e7a9f57b9413271f8e7693a2a8adeb6..1fb4c8f1122d3b58307bc0e1fab29978246ed7ca 100644 (file)
@@ -104,27 +104,25 @@ unsigned long io_apic_irqs;
 
 static inline unsigned int xen_io_apic_read(unsigned int apic, unsigned int reg)
 {
-       physdev_op_t op;
+       struct physdev_apic apic_op;
        int ret;
 
-       op.cmd = PHYSDEVOP_APIC_READ;
-       op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
-       op.u.apic_op.reg = reg;
-       ret = HYPERVISOR_physdev_op(&op);
+       apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
+       apic_op.reg = reg;
+       ret = HYPERVISOR_physdev_op(PHYSDEVOP_apic_read, &apic_op);
        if (ret)
                return ret;
-       return op.u.apic_op.value;
+       return apic_op.value;
 }
 
 static inline void xen_io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
 {
-       physdev_op_t op;
+       struct physdev_apic apic_op;
 
-       op.cmd = PHYSDEVOP_APIC_WRITE;
-       op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
-       op.u.apic_op.reg = reg;
-       op.u.apic_op.value = value;
-       HYPERVISOR_physdev_op(&op);
+       apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
+       apic_op.reg = reg;
+       apic_op.value = value;
+       HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op);
 }
 
 #define io_apic_read(a,r)    xen_io_apic_read(a,r)
@@ -869,22 +867,21 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mostly;
 
 int assign_irq_vector(int irq)
 {
-       physdev_op_t op;
+       struct physdev_irq irq_op;
   
        BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
        if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0)
                return IO_APIC_VECTOR(irq);
 
-       op.cmd = PHYSDEVOP_ASSIGN_VECTOR;
-       op.u.irq_op.irq = irq;
-       if (HYPERVISOR_physdev_op(&op))
+       irq_op.irq = irq;
+       if (HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op))
                return -ENOSPC;
 
-       vector_irq[op.u.irq_op.vector] = irq;
+       vector_irq[irq_op.vector] = irq;
        if (irq != AUTO_ASSIGN)
-               IO_APIC_VECTOR(irq) = op.u.irq_op.vector;
+               IO_APIC_VECTOR(irq) = irq_op.vector;
 
-       return op.u.irq_op.vector;
+       return irq_op.vector;
 }
 
 extern void (*interrupt[NR_IRQS])(void);
index 1b628dff54c06a28a4ef4efcf3c8f7c634577b8a..19bca3e8c428df40e0d69321ce05887a2638c16d 100644 (file)
@@ -28,8 +28,8 @@
 
 asmlinkage long sys_iopl(unsigned int new_iopl, struct pt_regs *regs)
 {
-        unsigned int old_iopl = current->thread.iopl;
-        physdev_op_t op;
+       unsigned int old_iopl = current->thread.iopl;
+       struct physdev_set_iopl set_iopl;
 
        if (new_iopl > 3)
                return -EINVAL;
@@ -42,9 +42,8 @@ asmlinkage long sys_iopl(unsigned int new_iopl, struct pt_regs *regs)
        current->thread.iopl = new_iopl;
 
        /* Force the change at ring 0. */
-       op.cmd             = PHYSDEVOP_SET_IOPL;
-       op.u.set_iopl.iopl = (new_iopl == 0) ? 1 : new_iopl;
-       HYPERVISOR_physdev_op(&op);
+       set_iopl.iopl = (new_iopl == 0) ? 1 : new_iopl;
+       HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
 
        return 0;
 }
index 7127fb57f367193fce7adbf07c1368a489e6d977..c761d703edb837a5a68b4f169b2d422b3400a984 100644 (file)
@@ -293,9 +293,7 @@ void exit_thread(void)
                struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
 #endif
 #ifdef CONFIG_XEN
-               static physdev_op_t iobmp_op = {
-                       .cmd = PHYSDEVOP_SET_IOBITMAP
-               };
+               struct physdev_set_iobitmap iobmp_op = { 0 };
 #endif
 
                kfree(t->io_bitmap_ptr);
@@ -308,7 +306,7 @@ void exit_thread(void)
                put_cpu();
 #endif
 #ifdef CONFIG_XEN
-               HYPERVISOR_physdev_op(&iobmp_op);
+               HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &iobmp_op);
 #endif
                t->io_bitmap_max = 0;
        }
@@ -478,7 +476,8 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 #ifndef CONFIG_X86_NO_TSS
        struct tss_struct *tss = &per_cpu(init_tss, cpu);
 #endif
-       physdev_op_t iopl_op, iobmp_op;
+       struct physdev_set_iopl iopl_op;
+       struct physdev_set_iobitmap iobmp_op;
        multicall_entry_t _mcl[8], *mcl = _mcl;
 
        /*
@@ -518,22 +517,19 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 #undef C
 
        if (unlikely(prev->iopl != next->iopl)) {
-               iopl_op.cmd             = PHYSDEVOP_SET_IOPL;
-               iopl_op.u.set_iopl.iopl = (next->iopl == 0) ? 1 : next->iopl;
+               iopl_op.iopl = (next->iopl == 0) ? 1 : next->iopl;
                mcl->op      = __HYPERVISOR_physdev_op;
-               mcl->args[0] = (unsigned long)&iopl_op;
+               mcl->args[0] = PHYSDEVOP_set_iopl;
+               mcl->args[1] = (unsigned long)&iopl_op;
                mcl++;
        }
 
        if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) {
-               iobmp_op.cmd                     =
-                       PHYSDEVOP_SET_IOBITMAP;
-               iobmp_op.u.set_iobitmap.bitmap   =
-                       (char *)next->io_bitmap_ptr;
-               iobmp_op.u.set_iobitmap.nr_ports =
-                       next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
+               iobmp_op.bitmap   = (char *)next->io_bitmap_ptr;
+               iobmp_op.nr_ports = next->io_bitmap_ptr ? IO_BITMAP_BITS : 0;
                mcl->op      = __HYPERVISOR_physdev_op;
-               mcl->args[0] = (unsigned long)&iobmp_op;
+               mcl->args[0] = PHYSDEVOP_set_iobitmap;
+               mcl->args[1] = (unsigned long)&iobmp_op;
                mcl++;
        }
 
index 30f8b405137e5ef80de4edaa8105176939d60223..df9c1ddbf6fc8537aa9d1127f9619c807422e2b7 100644 (file)
@@ -959,11 +959,10 @@ void __init setup_arch(char **cmdline_p)
 
 #ifdef CONFIG_XEN
        {
-               physdev_op_t op;
+               struct physdev_set_iopl set_iopl;
 
-               op.cmd             = PHYSDEVOP_SET_IOPL;
-               op.u.set_iopl.iopl = 1;
-               HYPERVISOR_physdev_op(&op);
+               set_iopl.iopl = 1;
+               HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
 
                if (xen_start_info->flags & SIF_INITDOMAIN) {
                        if (!(xen_start_info->flags & SIF_PRIVILEGED))
index 054e1397deb77e5af255cffe9f7e1d4edfc9d167..21487f54d4eb62d3cef980c89d30c4904c23c423 100644 (file)
@@ -13,7 +13,7 @@ config XEN
 if XEN
 config XEN_INTERFACE_VERSION
        hex
-       default 0x00030201
+       default 0x00030202
 
 menu "XEN"
 
index ac2b96149048564d4bf3b4f62638e913d3875d14..15ff3d1b5aefa53fa2d31f75a3430409f9482dcf 100644 (file)
@@ -101,10 +101,7 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
 {
        blkif_sring_t *sring;
        int err;
-       evtchn_op_t op = {
-               .cmd = EVTCHNOP_bind_interdomain,
-               .u.bind_interdomain.remote_dom = blkif->domid,
-               .u.bind_interdomain.remote_port = evtchn };
+       struct evtchn_bind_interdomain bind_interdomain;
 
        /* Already connected through? */
        if (blkif->irq)
@@ -119,14 +116,18 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
                return err;
        }
 
-       err = HYPERVISOR_event_channel_op(&op);
+       bind_interdomain.remote_dom  = blkif->domid;
+       bind_interdomain.remote_port = evtchn;
+
+       err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+                                         &bind_interdomain);
        if (err) {
                unmap_frontend_page(blkif);
                free_vm_area(blkif->blk_ring_area);
                return err;
        }
 
-       blkif->evtchn = op.u.bind_interdomain.local_port;
+       blkif->evtchn = bind_interdomain.local_port;
 
        sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
        BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
index f341f9ac33c597ff4ea13cb201401fcee923f2bc..60ef8d305cd70f2943787e96eb533476bf90e5f0 100644 (file)
@@ -70,10 +70,7 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
 {
        blkif_sring_t *sring;
        int err;
-       evtchn_op_t op = {
-               .cmd = EVTCHNOP_bind_interdomain,
-               .u.bind_interdomain.remote_dom  = blkif->domid,
-               .u.bind_interdomain.remote_port = evtchn };
+       struct evtchn_bind_interdomain bind_interdomain;
 
        if ((blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL)
                return -ENOMEM;
@@ -84,14 +81,18 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
                return err;
        }
 
-       err = HYPERVISOR_event_channel_op(&op);
+       bind_interdomain.remote_dom  = blkif->domid;
+       bind_interdomain.remote_port = evtchn;
+
+       err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+                                         &bind_interdomain);
        if (err) {
                unmap_frontend_page(blkif);
                free_vm_area(blkif->blk_ring_area);
                return err;
        }
 
-       blkif->evtchn = op.u.bind_interdomain.local_port;
+       blkif->evtchn = bind_interdomain.local_port;
 
        sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
        BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
index 92888ac62ae681e80d297d306ab6ffb1f0b7f628..d51a9861080807f42ba3f433aafc2a2a5efd9ead 100644 (file)
@@ -103,7 +103,7 @@ DEFINE_PER_CPU(int, ipi_to_irq[NR_IPIS]);
 static int irq_bindcount[NR_IRQS];
 
 /* Bitmap indicating which PIRQs require Xen to be notified on unmask. */
-static unsigned long pirq_needs_unmask_notify[NR_PIRQS/sizeof(unsigned long)];
+static unsigned long pirq_needs_eoi[NR_PIRQS/sizeof(unsigned long)];
 
 #ifdef CONFIG_SMP
 
@@ -258,16 +258,18 @@ static int bind_evtchn_to_irq(unsigned int evtchn)
 
 static int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
 {
-       evtchn_op_t op = { .cmd = EVTCHNOP_bind_virq };
+       struct evtchn_bind_virq bind_virq;
        int evtchn, irq;
 
        spin_lock(&irq_mapping_update_lock);
 
        if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1) {
-               op.u.bind_virq.virq = virq;
-               op.u.bind_virq.vcpu = cpu;
-               BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
-               evtchn = op.u.bind_virq.port;
+               bind_virq.virq = virq;
+               bind_virq.vcpu = cpu;
+               if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
+                                               &bind_virq) != 0)
+                       BUG();
+               evtchn = bind_virq.port;
 
                irq = find_unbound_irq();
                evtchn_to_irq[evtchn] = irq;
@@ -287,15 +289,17 @@ static int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
 
 static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
 {
-       evtchn_op_t op = { .cmd = EVTCHNOP_bind_ipi };
+       struct evtchn_bind_ipi bind_ipi;
        int evtchn, irq;
 
        spin_lock(&irq_mapping_update_lock);
 
        if ((irq = per_cpu(ipi_to_irq, cpu)[ipi]) == -1) {
-               op.u.bind_ipi.vcpu = cpu;
-               BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
-               evtchn = op.u.bind_ipi.port;
+               bind_ipi.vcpu = cpu;
+               if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi,
+                                               &bind_ipi) != 0)
+                       BUG();
+               evtchn = bind_ipi.port;
 
                irq = find_unbound_irq();
                evtchn_to_irq[evtchn] = irq;
@@ -315,14 +319,15 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
 
 static void unbind_from_irq(unsigned int irq)
 {
-       evtchn_op_t op = { .cmd = EVTCHNOP_close };
+       struct evtchn_close close;
        int evtchn = evtchn_from_irq(irq);
 
        spin_lock(&irq_mapping_update_lock);
 
        if ((--irq_bindcount[irq] == 0) && VALID_EVTCHN(evtchn)) {
-               op.u.close.port = evtchn;
-               BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+               close.port = evtchn;
+               if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
+                       BUG();
 
                switch (type_from_irq(irq)) {
                case IRQT_VIRQ:
@@ -428,7 +433,7 @@ static void do_nothing_function(void *ign)
 /* Rebind an evtchn so that it gets delivered to a specific cpu */
 static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
 {
-       evtchn_op_t op = { .cmd = EVTCHNOP_bind_vcpu };
+       struct evtchn_bind_vcpu bind_vcpu;
        int evtchn;
 
        spin_lock(&irq_mapping_update_lock);
@@ -440,15 +445,15 @@ static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
        }
 
        /* Send future instances of this interrupt to other vcpu. */
-       op.u.bind_vcpu.port = evtchn;
-       op.u.bind_vcpu.vcpu = tcpu;
+       bind_vcpu.port = evtchn;
+       bind_vcpu.vcpu = tcpu;
 
        /*
         * If this fails, it usually just indicates that we're dealing with a 
         * virq or IPI channel, which don't actually need to be rebound. Ignore
         * it, but don't do the xenlinux-level rebind in that case.
         */
-       if (HYPERVISOR_event_channel_op(&op) >= 0)
+       if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0)
                bind_evtchn_to_cpu(evtchn, tcpu);
 
        spin_unlock(&irq_mapping_update_lock);
@@ -544,22 +549,19 @@ static struct hw_interrupt_type dynirq_type = {
 
 static inline void pirq_unmask_notify(int pirq)
 {
-       physdev_op_t op;
-       if (unlikely(test_bit(pirq, &pirq_needs_unmask_notify[0]))) {
-               op.cmd = PHYSDEVOP_IRQ_UNMASK_NOTIFY;
-               (void)HYPERVISOR_physdev_op(&op);
-       }
+       struct physdev_eoi eoi = { .irq = pirq };
+       if (unlikely(test_bit(pirq, &pirq_needs_eoi[0])))
+               (void)HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi);
 }
 
 static inline void pirq_query_unmask(int pirq)
 {
-       physdev_op_t op;
-       op.cmd = PHYSDEVOP_IRQ_STATUS_QUERY;
-       op.u.irq_status_query.irq = pirq;
-       (void)HYPERVISOR_physdev_op(&op);
-       clear_bit(pirq, &pirq_needs_unmask_notify[0]);
-       if (op.u.irq_status_query.flags & PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY)
-               set_bit(pirq, &pirq_needs_unmask_notify[0]);
+       struct physdev_irq_status_query irq_status;
+       irq_status.irq = pirq;
+       (void)HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status);
+       clear_bit(pirq, &pirq_needs_eoi[0]);
+       if (irq_status.flags & XENIRQSTAT_needs_eoi)
+               set_bit(pirq, &pirq_needs_eoi[0]);
 }
 
 /*
@@ -570,22 +572,22 @@ static inline void pirq_query_unmask(int pirq)
 
 static unsigned int startup_pirq(unsigned int irq)
 {
-       evtchn_op_t op = { .cmd = EVTCHNOP_bind_pirq };
+       struct evtchn_bind_pirq bind_pirq;
        int evtchn = evtchn_from_irq(irq);
 
        if (VALID_EVTCHN(evtchn))
                goto out;
 
-       op.u.bind_pirq.pirq  = irq;
+       bind_pirq.pirq  = irq;
        /* NB. We are happy to share unless we are probing. */
-       op.u.bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE;
-       if (HYPERVISOR_event_channel_op(&op) != 0) {
+       bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE;
+       if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &bind_pirq) != 0) {
                if (!probing_irq(irq))
                        printk(KERN_INFO "Failed to obtain physical IRQ %d\n",
                               irq);
                return 0;
        }
-       evtchn = op.u.bind_pirq.port;
+       evtchn = bind_pirq.port;
 
        pirq_query_unmask(irq_to_pirq(irq));
 
@@ -602,7 +604,7 @@ static unsigned int startup_pirq(unsigned int irq)
 
 static void shutdown_pirq(unsigned int irq)
 {
-       evtchn_op_t op = { .cmd = EVTCHNOP_close };
+       struct evtchn_close close;
        int evtchn = evtchn_from_irq(irq);
 
        if (!VALID_EVTCHN(evtchn))
@@ -610,8 +612,9 @@ static void shutdown_pirq(unsigned int irq)
 
        mask_evtchn(evtchn);
 
-       op.u.close.port = evtchn;
-       BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+       close.port = evtchn;
+       if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
+               BUG();
 
        bind_evtchn_to_cpu(evtchn, 0);
        evtchn_to_irq[evtchn] = -1;
@@ -703,9 +706,8 @@ void unmask_evtchn(int port)
 
        /* Slow path (hypercall) if this is a non-local port. */
        if (unlikely(cpu != cpu_from_evtchn(port))) {
-               evtchn_op_t op = { .cmd = EVTCHNOP_unmask,
-                                  .u.unmask.port = port };
-               (void)HYPERVISOR_event_channel_op(&op);
+               struct evtchn_unmask unmask = { .port = port };
+               (void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask, &unmask);
                return;
        }
 
@@ -728,8 +730,9 @@ EXPORT_SYMBOL_GPL(unmask_evtchn);
 
 void irq_resume(void)
 {
-       evtchn_op_t op;
-       int         cpu, pirq, virq, ipi, irq, evtchn;
+       struct evtchn_bind_virq bind_virq;
+       struct evtchn_bind_ipi  bind_ipi;
+       int cpu, pirq, virq, ipi, irq, evtchn;
 
        init_evtchn_cpu_bindings();
 
@@ -763,12 +766,12 @@ void irq_resume(void)
                BUG_ON(irq_info[irq] != mk_irq_info(IRQT_VIRQ, virq, 0));
 
                /* Get a new binding from Xen. */
-               memset(&op, 0, sizeof(op));
-               op.cmd              = EVTCHNOP_bind_virq;
-               op.u.bind_virq.virq = virq;
-               op.u.bind_virq.vcpu = 0;
-               BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
-               evtchn = op.u.bind_virq.port;
+               bind_virq.virq = virq;
+               bind_virq.vcpu = 0;
+               if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
+                                               &bind_virq) != 0)
+                       BUG();
+               evtchn = bind_virq.port;
 
                /* Record the new mapping. */
                evtchn_to_irq[evtchn] = irq;
@@ -786,11 +789,11 @@ void irq_resume(void)
                BUG_ON(irq_info[irq] != mk_irq_info(IRQT_IPI, ipi, 0));
 
                /* Get a new binding from Xen. */
-               memset(&op, 0, sizeof(op));
-               op.cmd = EVTCHNOP_bind_ipi;
-               op.u.bind_ipi.vcpu = 0;
-               BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
-               evtchn = op.u.bind_ipi.port;
+               bind_ipi.vcpu = 0;
+               if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi,
+                                               &bind_ipi) != 0)
+                       BUG();
+               evtchn = bind_ipi.port;
 
                /* Record the new mapping. */
                evtchn_to_irq[evtchn] = irq;
index 2975fe070e61ec2091b2e2b75aad76ae9a056004..8b9cdbbb310318519d436669d0a47db0301b811d 100644 (file)
@@ -206,68 +206,71 @@ static int evtchn_ioctl(struct inode *inode, struct file *file,
        int rc;
        struct per_user_data *u = file->private_data;
        void __user *uarg = (void __user *) arg;
-       evtchn_op_t op = { 0 };
 
        switch (cmd) {
        case IOCTL_EVTCHN_BIND_VIRQ: {
                struct ioctl_evtchn_bind_virq bind;
+               struct evtchn_bind_virq bind_virq;
 
                rc = -EFAULT;
                if (copy_from_user(&bind, uarg, sizeof(bind)))
                        break;
 
-               op.cmd = EVTCHNOP_bind_virq;
-               op.u.bind_virq.virq = bind.virq;
-               op.u.bind_virq.vcpu = 0;
-               rc = HYPERVISOR_event_channel_op(&op);
+               bind_virq.virq = bind.virq;
+               bind_virq.vcpu = 0;
+               rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
+                                                &bind_virq);
                if (rc != 0)
                        break;
 
-               rc = op.u.bind_virq.port;
+               rc = bind_virq.port;
                evtchn_bind_to_user(u, rc);
                break;
        }
 
        case IOCTL_EVTCHN_BIND_INTERDOMAIN: {
                struct ioctl_evtchn_bind_interdomain bind;
+               struct evtchn_bind_interdomain bind_interdomain;
 
                rc = -EFAULT;
                if (copy_from_user(&bind, uarg, sizeof(bind)))
                        break;
 
-               op.cmd = EVTCHNOP_bind_interdomain;
-               op.u.bind_interdomain.remote_dom  = bind.remote_domain;
-               op.u.bind_interdomain.remote_port = bind.remote_port;
-               rc = HYPERVISOR_event_channel_op(&op);
+               bind_interdomain.remote_dom  = bind.remote_domain;
+               bind_interdomain.remote_port = bind.remote_port;
+               rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+                                                &bind_interdomain);
                if (rc != 0)
                        break;
 
-               rc = op.u.bind_interdomain.local_port;
+               rc = bind_interdomain.local_port;
                evtchn_bind_to_user(u, rc);
                break;
        }
 
        case IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
                struct ioctl_evtchn_bind_unbound_port bind;
+               struct evtchn_alloc_unbound alloc_unbound;
 
                rc = -EFAULT;
                if (copy_from_user(&bind, uarg, sizeof(bind)))
                        break;
 
-               op.cmd = EVTCHNOP_alloc_unbound;
-               op.u.alloc_unbound.dom        = DOMID_SELF;
-               op.u.alloc_unbound.remote_dom = bind.remote_domain;
-               rc = HYPERVISOR_event_channel_op(&op);
+               alloc_unbound.dom        = DOMID_SELF;
+               alloc_unbound.remote_dom = bind.remote_domain;
+               rc = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
+                                                &alloc_unbound);
                if (rc != 0)
                        break;
 
-               rc = op.u.alloc_unbound.port;
+               rc = alloc_unbound.port;
                evtchn_bind_to_user(u, rc);
                break;
        }
 
        case IOCTL_EVTCHN_UNBIND: {
                struct ioctl_evtchn_unbind unbind;
+               struct evtchn_close close;
                int ret;
 
                rc = -EFAULT;
@@ -291,9 +294,8 @@ static int evtchn_ioctl(struct inode *inode, struct file *file,
 
                spin_unlock_irq(&port_user_lock);
 
-               op.cmd = EVTCHNOP_close;
-               op.u.close.port = unbind.port;
-               ret = HYPERVISOR_event_channel_op(&op);
+               close.port = unbind.port;
+               ret = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
                BUG_ON(ret);
 
                rc = 0;
@@ -379,7 +381,7 @@ static int evtchn_release(struct inode *inode, struct file *filp)
 {
        int i;
        struct per_user_data *u = filp->private_data;
-       evtchn_op_t op = { 0 };
+       struct evtchn_close close;
 
        spin_lock_irq(&port_user_lock);
 
@@ -393,9 +395,8 @@ static int evtchn_release(struct inode *inode, struct file *filp)
                port_user[i] = NULL;
                mask_evtchn(i);
 
-               op.cmd = EVTCHNOP_close;
-               op.u.close.port = i;
-               ret = HYPERVISOR_event_channel_op(&op);
+               close.port = i;
+               ret = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
                BUG_ON(ret);
        }
 
index f4407bccdcbcf3439634862ebc129dcbc5dffe87..10095a6abf79ee8b1ca271d9446237751e43393c 100644 (file)
@@ -213,10 +213,7 @@ int netif_map(netif_t *netif, unsigned long tx_ring_ref,
        int err = -ENOMEM;
        netif_tx_sring_t *txs;
        netif_rx_sring_t *rxs;
-       evtchn_op_t op = {
-               .cmd = EVTCHNOP_bind_interdomain,
-               .u.bind_interdomain.remote_dom = netif->domid,
-               .u.bind_interdomain.remote_port = evtchn };
+       struct evtchn_bind_interdomain bind_interdomain;
 
        /* Already connected through? */
        if (netif->irq)
@@ -233,11 +230,15 @@ int netif_map(netif_t *netif, unsigned long tx_ring_ref,
        if (err)
                goto err_map;
 
-       err = HYPERVISOR_event_channel_op(&op);
+       bind_interdomain.remote_dom = netif->domid;
+       bind_interdomain.remote_port = evtchn;
+
+       err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+                                         &bind_interdomain);
        if (err)
                goto err_hypervisor;
 
-       netif->evtchn = op.u.bind_interdomain.local_port;
+       netif->evtchn = bind_interdomain.local_port;
 
        netif->irq = bind_evtchn_to_irqhandler(
                netif->evtchn, netif_be_int, 0, netif->dev->name, netif);
index 5b51e3271de192207f62c24315ac881076a6c89e..a5b9c73813fb3396ee72360140a0506be7d1019c 100644 (file)
@@ -35,7 +35,7 @@
 static struct proc_dir_entry *privcmd_intf;
 static struct proc_dir_entry *capabilities_intf;
 
-#define NR_HYPERCALLS 32
+#define NR_HYPERCALLS 64
 static DECLARE_BITMAP(hypercall_permission_map, NR_HYPERCALLS);
 
 static int privcmd_ioctl(struct inode *inode, struct file *file,
index 7a7ca4c7ed4c4a8fd1103d4728191271f9e62c96..347ed1ab029a38b0686a0c4b478fb105b8c10029 100644 (file)
@@ -112,11 +112,7 @@ static void unmap_frontend_page(tpmif_t *tpmif)
 int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
 {
        int err;
-       evtchn_op_t op = {
-               .cmd = EVTCHNOP_bind_interdomain,
-               .u.bind_interdomain.remote_dom = tpmif->domid,
-               .u.bind_interdomain.remote_port = evtchn,
-       };
+       struct evtchn_bind_interdomain bind_interdomain;
 
        if (tpmif->irq) {
                return 0;
@@ -131,14 +127,19 @@ int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
                return err;
        }
 
-       err = HYPERVISOR_event_channel_op(&op);
+
+       bind_interdomain.remote_dom  = tpmif->domid;
+       bind_interdomain.remote_port = evtchn;
+
+       err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+                                         &bind_interdomain);
        if (err) {
                unmap_frontend_page(tpmif);
                free_vm_area(tpmif->tx_area);
                return err;
        }
 
-       tpmif->evtchn = op.u.bind_interdomain.local_port;
+       tpmif->evtchn = bind_interdomain.local_port;
 
        tpmif->tx = (tpmif_tx_interface_t *)tpmif->tx_area->addr;
 
index d4059b18c2cfe3e9f4982e05ff5bad812f97df20..5985ebefed795f49a00ed5e3781c71efd6994d5f 100644 (file)
@@ -214,16 +214,19 @@ EXPORT_SYMBOL_GPL(xenbus_grant_ring);
 
 int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port)
 {
-       evtchn_op_t op = {
-               .cmd = EVTCHNOP_alloc_unbound,
-               .u.alloc_unbound.dom = DOMID_SELF,
-               .u.alloc_unbound.remote_dom = dev->otherend_id
-       };
-       int err = HYPERVISOR_event_channel_op(&op);
+       struct evtchn_alloc_unbound alloc_unbound;
+       int err;
+
+       alloc_unbound.dom        = DOMID_SELF;
+       alloc_unbound.remote_dom = dev->otherend_id;
+
+       err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
+                                         &alloc_unbound);
        if (err)
                xenbus_dev_fatal(dev, err, "allocating event channel");
        else
-               *port = op.u.alloc_unbound.port;
+               *port = alloc_unbound.port;
+
        return err;
 }
 EXPORT_SYMBOL_GPL(xenbus_alloc_evtchn);
@@ -231,18 +234,21 @@ EXPORT_SYMBOL_GPL(xenbus_alloc_evtchn);
 
 int xenbus_bind_evtchn(struct xenbus_device *dev, int remote_port, int *port)
 {
-       evtchn_op_t op = {
-               .cmd = EVTCHNOP_bind_interdomain,
-               .u.bind_interdomain.remote_dom = dev->otherend_id,
-               .u.bind_interdomain.remote_port = remote_port,
-       };
-       int err = HYPERVISOR_event_channel_op(&op);
+       struct evtchn_bind_interdomain bind_interdomain;
+       int err;
+
+       bind_interdomain.remote_dom  = dev->otherend_id;
+       bind_interdomain.remote_port = remote_port,
+
+       err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+                                         &bind_interdomain);
        if (err)
                xenbus_dev_fatal(dev, err,
                                 "binding to event channel %d from domain %d",
                                 remote_port, dev->otherend_id);
        else
-               *port = op.u.bind_interdomain.local_port;
+               *port = bind_interdomain.local_port;
+
        return err;
 }
 EXPORT_SYMBOL_GPL(xenbus_bind_evtchn);
@@ -250,13 +256,15 @@ EXPORT_SYMBOL_GPL(xenbus_bind_evtchn);
 
 int xenbus_free_evtchn(struct xenbus_device *dev, int port)
 {
-       evtchn_op_t op = {
-               .cmd = EVTCHNOP_close,
-               .u.close.port = port,
-       };
-       int err = HYPERVISOR_event_channel_op(&op);
+       struct evtchn_close close;
+       int err;
+
+       close.port = port;
+
+       err = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
        if (err)
                xenbus_dev_error(dev, err, "freeing event channel %d", port);
+
        return err;
 }
 
index 09bedf7b66511ca5108124486c23768d81d67fea..e0c05915a5df7a9d28e69589582cffa085f073c9 100644 (file)
@@ -981,7 +981,7 @@ static int __init xenbus_probe_init(void)
        dom0 = (xen_start_info->store_evtchn == 0);
 
        if (dom0) {
-               evtchn_op_t op = { 0 };
+               struct evtchn_alloc_unbound alloc_unbound;
 
                /* Allocate page. */
                page = get_zeroed_page(GFP_KERNEL);
@@ -993,15 +993,15 @@ static int __init xenbus_probe_init(void)
                                   PAGE_SHIFT);
 
                /* Next allocate a local port which xenstored can bind to */
-               op.cmd = EVTCHNOP_alloc_unbound;
-               op.u.alloc_unbound.dom        = DOMID_SELF;
-               op.u.alloc_unbound.remote_dom = 0;
+               alloc_unbound.dom        = DOMID_SELF;
+               alloc_unbound.remote_dom = 0;
 
-               err = HYPERVISOR_event_channel_op(&op);
+               err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
+                                                 &alloc_unbound);
                if (err == -ENOSYS)
                        goto err;
                BUG_ON(err);
-               xen_start_info->store_evtchn = op.u.alloc_unbound.port;
+               xen_start_info->store_evtchn = alloc_unbound.port;
 
                /* And finally publish the above info in /proc/xen */
                xsd_kva_intf = create_xen_proc_entry("xsd_kva", 0600);
index 491362c9769e8e99569dae35a806bfe643db56d8..a5ffa3a53b55e648eca5ebf93ac97b8687a0ebff 100644 (file)
@@ -245,9 +245,16 @@ HYPERVISOR_update_va_mapping(
 
 static inline int
 HYPERVISOR_event_channel_op(
-       void *op)
+       int cmd, void *arg)
 {
-       return _hypercall1(int, event_channel_op, op);
+       int rc = _hypercall2(int, event_channel_op, cmd, arg);
+       if (unlikely(rc == -ENOSYS)) {
+               struct evtchn_op op;
+               op.cmd = cmd;
+               memcpy(&op.u, arg, sizeof(op.u));
+               rc = _hypercall1(int, event_channel_op_compat, &op);
+       }
+       return rc;
 }
 
 static inline int
@@ -266,9 +273,16 @@ HYPERVISOR_console_io(
 
 static inline int
 HYPERVISOR_physdev_op(
-       void *physdev_op)
+       int cmd, void *arg)
 {
-       return _hypercall1(int, physdev_op, physdev_op);
+       int rc = _hypercall2(int, physdev_op, cmd, arg);
+       if (unlikely(rc == -ENOSYS)) {
+               struct physdev_op op;
+               op.cmd = cmd;
+               memcpy(&op.u, arg, sizeof(op.u));
+               rc = _hypercall1(int, physdev_op_compat, &op);
+       }
+       return rc;
 }
 
 static inline int
index 8e135b40541b4932963c4d26bfdf2d59763d25e1..e4ec1309d39ed48f3bb1fed1c76e4f6346653fec 100644 (file)
@@ -40,6 +40,8 @@
 #include <linux/errno.h>
 #include <xen/interface/xen.h>
 #include <xen/interface/dom0_ops.h>
+#include <xen/interface/event_channel.h>
+#include <xen/interface/physdev.h>
 #include <xen/interface/sched.h>
 #include <xen/interface/nmi.h>
 #include <asm/ptrace.h>
index 6c028021443c753996ffb23a7edb892b793bc6f6..fabab38fa29c12d8a69dc27b97fb8e6c2ee23bc9 100644 (file)
@@ -534,12 +534,11 @@ static inline void __load_esp0(struct tss_struct *tss, struct thread_struct *thr
  */
 static inline void set_iopl_mask(unsigned mask)
 {
-       physdev_op_t op;
+       struct physdev_set_iopl set_iopl;
 
        /* Force the change at ring 0. */
-       op.cmd = PHYSDEVOP_SET_IOPL;
-       op.u.set_iopl.iopl = (mask == 0) ? 1 : (mask >> 12) & 3;
-       HYPERVISOR_physdev_op(&op);
+       set_iopl.iopl = (mask == 0) ? 1 : (mask >> 12) & 3;
+       HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
 }
 
 /* Forward declaration, a strange C thing */
index b0cced76784aed8bd1b2da3f0c5b67174b16721f..432026eea4ea06b6e490b10c3b25e70457c1401c 100644 (file)
@@ -202,9 +202,16 @@ HYPERVISOR_memory_op(
 
 static inline int
 HYPERVISOR_event_channel_op(
-    void *op)
+    int cmd, void *arg)
 {
-    return _hypercall1(int, event_channel_op, op);
+    int rc = _hypercall2(int, event_channel_op, cmd, arg);
+    if (unlikely(rc == -ENOSYS)) {
+        struct evtchn_op op;
+        op.cmd = cmd;
+        memcpy(&op.u, arg, sizeof(op.u));
+        rc = _hypercall1(int, event_channel_op_compat, &op);
+    }
+    return rc;
 }
 
 static inline int
@@ -223,9 +230,16 @@ HYPERVISOR_console_io(
 
 static inline int
 HYPERVISOR_physdev_op(
-    void *physdev_op)
+    int cmd, void *arg)
 {
-    return _hypercall1(int, physdev_op, physdev_op);
+    int rc = _hypercall2(int, physdev_op, cmd, arg);
+    if (unlikely(rc == -ENOSYS)) {
+        struct physdev_op op;
+        op.cmd = cmd;
+        memcpy(&op.u, arg, sizeof(op.u));
+        rc = _hypercall1(int, physdev_op_compat, &op);
+    }
+    return rc;
 }
 
 static inline int
index e92cc4fbdb62b5f9536e48981002689e94053131..ba17a56210fa7381e7c78ce861e5a9ee312d50e9 100644 (file)
@@ -40,6 +40,8 @@
 #include <linux/errno.h>
 #include <xen/interface/xen.h>
 #include <xen/interface/dom0_ops.h>
+#include <xen/interface/event_channel.h>
+#include <xen/interface/physdev.h>
 #include <xen/interface/sched.h>
 #include <asm/hypercall.h>
 #include <asm/ptrace.h>
index f75ae5819d6f5f70cd520da9fb5ce4dfb63fe378..be9933975edb856b124fab503a68e16783ce5490 100644 (file)
@@ -243,9 +243,16 @@ HYPERVISOR_update_va_mapping(
 
 static inline int
 HYPERVISOR_event_channel_op(
-       void *op)
+       int cmd, void *arg)
 {
-       return _hypercall1(int, event_channel_op, op);
+       int rc = _hypercall2(int, event_channel_op, cmd, arg);
+       if (unlikely(rc == -ENOSYS)) {
+               struct evtchn_op op;
+               op.cmd = cmd;
+               memcpy(&op.u, arg, sizeof(op.u));
+               rc = _hypercall1(int, event_channel_op_compat, &op);
+       }
+       return rc;
 }
 
 static inline int
@@ -264,9 +271,16 @@ HYPERVISOR_console_io(
 
 static inline int
 HYPERVISOR_physdev_op(
-       void *physdev_op)
+       int cmd, void *arg)
 {
-       return _hypercall1(int, physdev_op, physdev_op);
+       int rc = _hypercall2(int, physdev_op, cmd, arg);
+       if (unlikely(rc == -ENOSYS)) {
+               struct physdev_op op;
+               op.cmd = cmd;
+               memcpy(&op.u, arg, sizeof(op.u));
+               rc = _hypercall1(int, physdev_op_compat, &op);
+       }
+       return rc;
 }
 
 static inline int
index 100eb1cdaa18c638cc0acee491b6fc166870d074..4770663603fbe8b7367624f5a40c282bae432141 100644 (file)
@@ -101,10 +101,8 @@ static inline void clear_evtchn(int port)
 
 static inline void notify_remote_via_evtchn(int port)
 {
-       evtchn_op_t op;
-       op.cmd         = EVTCHNOP_send,
-       op.u.send.port = port;
-       (void)HYPERVISOR_event_channel_op(&op);
+       struct evtchn_send send = { .port = port };
+       (void)HYPERVISOR_event_channel_op(EVTCHNOP_send, &send);
 }
 
 /*
index 27d464bb2f3f8302e7936240973e2455761da16e..e43d210fafabab506000204cf5b5a37d22049293 100644 (file)
@@ -9,24 +9,25 @@
 #include "xc_private.h"
 
 
-static int do_evtchn_op(int xc_handle, evtchn_op_t *op)
+static int do_evtchn_op(int xc_handle, int cmd, void *arg, size_t arg_size)
 {
     int ret = -1;
     DECLARE_HYPERCALL;
 
     hypercall.op     = __HYPERVISOR_event_channel_op;
-    hypercall.arg[0] = (unsigned long)op;
+    hypercall.arg[0] = cmd;
+    hypercall.arg[1] = (unsigned long)arg;
 
-    if ( mlock(op, sizeof(*op)) != 0 )
+    if ( mlock(arg, arg_size) != 0 )
     {
-        PERROR("do_evtchn_op: op mlock failed");
+        PERROR("do_evtchn_op: arg mlock failed");
         goto out;
     }
 
     if ((ret = do_xen_hypercall(xc_handle, &hypercall)) < 0)
         ERROR("do_evtchn_op: HYPERVISOR_event_channel_op failed: %d", ret);
 
-    safe_munlock(op, sizeof(*op));
+    safe_munlock(arg, arg_size);
  out:
     return ret;
 }
@@ -37,13 +38,14 @@ int xc_evtchn_alloc_unbound(int xc_handle,
                             uint32_t remote_dom)
 {
     int         rc;
-    evtchn_op_t op = {
-        .cmd = EVTCHNOP_alloc_unbound,
-        .u.alloc_unbound.dom = (domid_t)dom,
-        .u.alloc_unbound.remote_dom = (domid_t)remote_dom };
+    struct evtchn_alloc_unbound arg = {
+        .dom = (domid_t)dom,
+        .remote_dom = (domid_t)remote_dom
+    };
 
-    if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 )
-        rc = op.u.alloc_unbound.port;
+    rc = do_evtchn_op(xc_handle, EVTCHNOP_alloc_unbound, &arg, sizeof(arg));
+    if ( rc == 0 )
+        rc = arg.port;
 
     return rc;
 }
@@ -54,14 +56,7 @@ int xc_evtchn_status(int xc_handle,
                      evtchn_port_t port,
                      xc_evtchn_status_t *status)
 {
-    int         rc;
-    evtchn_op_t op = {
-        .cmd           = EVTCHNOP_status,
-        .u.status.dom  = (domid_t)dom,
-        .u.status.port = port };
-
-    if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 )
-        memcpy(status, &op.u.status, sizeof(*status));
-
-    return rc;
+    status->dom  = (domid_t)dom;
+    status->port = port;
+    return do_evtchn_op(xc_handle, EVTCHNOP_status, status, sizeof(*status));
 }
index d07b7334e65acc7933d805d23a1c679cf6becc44..403605bf41113c3f1f884dccf89580f5f987992f 100644 (file)
@@ -106,12 +106,12 @@ void hyper_dom0_op(void)
     vmx_vcpu_increment_iip(vcpu);
 }
 
-void hyper_event_channel_op(void)
+void hyper_event_channel_op_compat(void)
 {
     VCPU *vcpu=current;
     u64 r32,ret;
     vcpu_get_gr_nat(vcpu,16,&r32);
-    ret=do_event_channel_op(guest_handle_from_ptr(r32, evtchn_op_t));
+    ret=do_event_channel_op_compat(guest_handle_from_ptr(r32, evtchn_op_t));
     vcpu_set_gr(vcpu, 8, ret, 0);
     vmx_vcpu_increment_iip(vcpu);
 }
index 81b3e646369af115bfa78761ed12333277739572..c9288b17940f3554063fddae4ec56a418d507a74 100644 (file)
@@ -1154,7 +1154,7 @@ hyper_call_table:
     data8 hyper_not_support     //hyper_multicall
     data8 hyper_not_support     //hyper_update_va_mapping
     data8 hyper_not_support     //hyper_set_timer_op       /* 15 */
-    data8 hyper_event_channel_op
+    data8 hyper_event_channel_op_compat
     data8 hyper_xen_version
     data8 hyper_not_support     //hyper_console_io
     data8 hyper_not_support     //hyper_physdev_op
index 72e6ecf7a3f6b7da9dff7b8e33debbee54426e83..ca1a103c3b42b583ab795cf20eb745771ffe7d2f 100644 (file)
@@ -27,6 +27,7 @@
 #include <xen/domain.h>
 
 extern unsigned long translate_domain_mpaddr(unsigned long);
+static long do_physdev_op_compat(int cmd, XEN_GUEST_HANDLE(void) arg);
 static long do_physdev_op(XEN_GUEST_HANDLE(physdev_op_t) uop);
 /* FIXME: where these declarations should be there ? */
 extern int dump_privop_counts_to_user(char *, int);
@@ -53,10 +54,10 @@ hypercall_t ia64_hypercall_table[] =
        (hypercall_t)do_multicall,
        (hypercall_t)do_ni_hypercall,           /* do_update_va_mapping */
        (hypercall_t)do_ni_hypercall,           /* do_set_timer_op */           /* 15 */
-       (hypercall_t)do_event_channel_op,
+       (hypercall_t)do_event_channel_op_compat,
        (hypercall_t)do_xen_version,
        (hypercall_t)do_console_io,
-       (hypercall_t)do_physdev_op,
+       (hypercall_t)do_physdev_op_compat,
        (hypercall_t)do_grant_table_op,                                         /* 20 */
        (hypercall_t)do_ni_hypercall,           /* do_vm_assist */
        (hypercall_t)do_ni_hypercall,           /* do_update_va_mapping_otherdomain */
@@ -68,7 +69,9 @@ hypercall_t ia64_hypercall_table[] =
        (hypercall_t)do_ni_hypercall,           /* do_nmi_op */
        (hypercall_t)do_sched_op,
        (hypercall_t)do_ni_hypercall,           /*  */                          /* 30 */
-       (hypercall_t)do_ni_hypercall            /*  */
+       (hypercall_t)do_ni_hypercall,           /*  */
+       (hypercall_t)do_event_channel_op,
+       (hypercall_t)do_physdev_op
        };
 
 uint32_t nr_hypercalls =
@@ -330,71 +333,117 @@ extern int
 iosapic_guest_write(
     unsigned long physbase, unsigned int reg, u32 pval);
 
-static long do_physdev_op(XEN_GUEST_HANDLE(physdev_op_t) uop)
+static long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
 {
-    struct physdev_op op;
+    int irq;
     long ret;
-    int  irq;
-
-    if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
-        return -EFAULT;
 
-    switch ( op.cmd )
+    switch ( cmd )
     {
-    case PHYSDEVOP_IRQ_UNMASK_NOTIFY:
+    case PHYSDEVOP_eoi: {
+        struct physdev_eoi eoi;
+        ret = -EFAULT;
+        if ( copy_from_guest(&eoi, arg, 1) != 0 )
+            break;
+        ret = pirq_guest_eoi(current->domain, eoi.irq);
+        break;
+    }
+
+    /* Legacy since 0x00030202. */
+    case PHYSDEVOP_IRQ_UNMASK_NOTIFY: {
         ret = pirq_guest_unmask(current->domain);
         break;
+    }
 
-    case PHYSDEVOP_IRQ_STATUS_QUERY:
-        irq = op.u.irq_status_query.irq;
+    case PHYSDEVOP_irq_status_query: {
+        struct physdev_irq_status_query irq_status_query;
+        ret = -EFAULT;
+        if ( copy_from_guest(&irq_status_query, arg, 1) != 0 )
+            break;
+        irq = irq_status_query.irq;
         ret = -EINVAL;
         if ( (irq < 0) || (irq >= NR_IRQS) )
             break;
-        op.u.irq_status_query.flags = 0;
+        irq_status_query.flags = 0;
         /* Edge-triggered interrupts don't need an explicit unmask downcall. */
         if ( !strstr(irq_desc[irq_to_vector(irq)].handler->typename, "edge") )
-            op.u.irq_status_query.flags |= PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY;
-        ret = 0;
+            irq_status_query.flags |= XENIRQSTAT_needs_eoi;
+        ret = copy_to_guest(arg, &irq_status_query, 1) ? -EFAULT : 0;
         break;
+    }
 
-    case PHYSDEVOP_APIC_READ:
+    case PHYSDEVOP_apic_read: {
+        struct physdev_apic apic;
+        ret = -EFAULT;
+        if ( copy_from_guest(&apic, arg, 1) != 0 )
+            break;
         ret = -EPERM;
         if ( !IS_PRIV(current->domain) )
             break;
-        ret = iosapic_guest_read(
-            op.u.apic_op.apic_physbase,
-            op.u.apic_op.reg,
-            &op.u.apic_op.value);
+        ret = iosapic_guest_read(apic.apic_physbase, apic.reg, &apic.value);
+        if ( copy_to_guest(arg, &apic, 1) != 0 )
+            ret = -EFAULT;
         break;
+    }
 
-    case PHYSDEVOP_APIC_WRITE:
+    case PHYSDEVOP_apic_write: {
+        struct physdev_apic apic;
+        ret = -EFAULT;
+        if ( copy_from_guest(&apic, arg, 1) != 0 )
+            break;
         ret = -EPERM;
         if ( !IS_PRIV(current->domain) )
             break;
-        ret = iosapic_guest_write(
-            op.u.apic_op.apic_physbase,
-            op.u.apic_op.reg,
-            op.u.apic_op.value);
+        ret = iosapic_guest_write(apic.apic_physbase, apic.reg, apic.value);
         break;
+    }
 
-    case PHYSDEVOP_ASSIGN_VECTOR:
+    case PHYSDEVOP_alloc_irq_vector: {
+        struct physdev_irq irq_op;
+
+        ret = -EFAULT;
+        if ( copy_from_guest(&irq_op, arg, 1) != 0 )
+            break;
+
+        ret = -EPERM;
         if ( !IS_PRIV(current->domain) )
-            return -EPERM;
+            break;
 
-        if ( (irq = op.u.irq_op.irq) >= NR_IRQS )
-            return -EINVAL;
+        ret = -EINVAL;
+        if ( (irq = irq_op.irq) >= NR_IRQS )
+            break;
         
-        op.u.irq_op.vector = assign_irq_vector(irq);
-        ret = 0;
+        irq_op.vector = assign_irq_vector(irq);
+        ret = copy_to_guest(arg, &irq_op, 1) ? -EFAULT : 0;
         break;
+    }
 
     default:
         ret = -EINVAL;
         break;
     }
 
-    if ( copy_to_guest(uop, &op, 1) )
-        ret = -EFAULT;
-
     return ret;
 }
+
+/* Legacy hypercall (as of 0x00030202). */
+static long do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop)
+{
+    struct physdev_op op;
+
+    if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
+        return -EFAULT;
+
+    return do_physdev_op(op.cmd, guest_handle_from_ptr(&uop.p->u, void));
+}
+
+/* Legacy hypercall (as of 0x00030202). */
+long do_event_channel_op_compat(XEN_GUEST_HANDLE(evtchn_op_t) uop)
+{
+    struct evtchn_op op;
+
+    if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
+        return -EFAULT;
+
+    return do_event_channel_op(op.cmd, guest_handle_from_ptr(&uop.p->u, void));
+}
index 5fbffdf82b55b52578a3e573111870032942dc83..c8f8ec5b9ec95975a08b28d1b2a0fc3be6aa6d25 100644 (file)
@@ -411,22 +411,40 @@ void __do_IRQ_guest(int irq)
     }
 }
 
+int pirq_guest_eoi(struct domain *d, int irq)
+{
+    irq_desc_t *desc;
+
+    if ( (irq < 0) || (irq >= NR_IRQS) )
+        return -EINVAL;
+
+    desc = &irq_desc[irq];
+    spin_lock_irq(&desc->lock);
+    if ( test_and_clear_bit(irq, &d->pirq_mask) &&
+         (--((irq_guest_action_t *)desc->action)->in_flight == 0) )
+        desc->handler->end(irq);
+    spin_unlock_irq(&desc->lock);
+
+    return 0;
+
+}
+
 int pirq_guest_unmask(struct domain *d)
 {
     irq_desc_t    *desc;
-    int            pirq;
+    int            irq;
     shared_info_t *s = d->shared_info;
 
-    for ( pirq = find_first_bit(d->pirq_mask, NR_PIRQS);
-          pirq < NR_PIRQS;
-          pirq = find_next_bit(d->pirq_mask, NR_PIRQS, pirq+1) )
+    for ( irq = find_first_bit(d->pirq_mask, NR_PIRQS);
+          irq < NR_PIRQS;
+          irq = find_next_bit(d->pirq_mask, NR_PIRQS, irq+1) )
     {
-        desc = &irq_desc[pirq];
+        desc = &irq_desc[irq];
         spin_lock_irq(&desc->lock);
-        if ( !test_bit(d->pirq_to_evtchn[pirq], &s->evtchn_mask[0]) &&
-             test_and_clear_bit(pirq, &d->pirq_mask) &&
+        if ( !test_bit(d->pirq_to_evtchn[irq], &s->evtchn_mask[0]) &&
+             test_and_clear_bit(irq, &d->pirq_mask) &&
              (--((irq_guest_action_t *)desc->action)->in_flight == 0) )
-            desc->handler->end(pirq);
+            desc->handler->end(irq);
         spin_unlock_irq(&desc->lock);
     }
 
index e4d64521410639ab04a45aab8df22ddbe76ff82c..fad402d31423659089af8140d51599e6080a1068 100644 (file)
@@ -10,6 +10,7 @@ subdir-$(x86_64) += x86_64
 obj-y += apic.o
 obj-y += audit.o
 obj-y += bitops.o
+obj-y += compat.o
 obj-y += delay.o
 obj-y += dmi_scan.o
 obj-y += dom0_ops.o
diff --git a/xen/arch/x86/compat.c b/xen/arch/x86/compat.c
new file mode 100644 (file)
index 0000000..431c456
--- /dev/null
@@ -0,0 +1,32 @@
+/******************************************************************************
+ * compat.c
+ * 
+ * Implementations of legacy hypercalls. These call through to the new
+ * hypercall after doing necessary argument munging.
+ */
+
+#include <xen/config.h>
+#include <xen/guest_access.h>
+#include <xen/hypercall.h>
+
+/* Legacy hypercall (as of 0x00030202). */
+long do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop)
+{
+    struct physdev_op op;
+
+    if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
+        return -EFAULT;
+
+    return do_physdev_op(op.cmd, (XEN_GUEST_HANDLE(void)) { &uop.p->u });
+}
+
+/* Legacy hypercall (as of 0x00030202). */
+long do_event_channel_op_compat(XEN_GUEST_HANDLE(evtchn_op_t) uop)
+{
+    struct evtchn_op op;
+
+    if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
+        return -EFAULT;
+
+    return do_event_channel_op(op.cmd, (XEN_GUEST_HANDLE(void)) {&uop.p->u });
+}
index 41bfb98e7eb0073a68c79d4898be8512c10dc3a6..c144b9f415f11a51570533577d1a3e129e464d51 100644 (file)
@@ -293,52 +293,75 @@ static void flush_all_pending_eoi(void *unused)
     flush_ready_eoi(NULL);
 }
 
-int pirq_guest_unmask(struct domain *d)
+static void __pirq_guest_eoi(struct domain *d, int irq)
 {
     irq_desc_t         *desc;
     irq_guest_action_t *action;
-    cpumask_t           cpu_eoi_map = CPU_MASK_NONE;
-    unsigned int        pirq, cpu = smp_processor_id();
-    shared_info_t      *s = d->shared_info;
+    cpumask_t           cpu_eoi_map;
+
+    desc   = &irq_desc[irq_to_vector(irq)];
+    action = (irq_guest_action_t *)desc->action;
+
+    spin_lock_irq(&desc->lock);
+
+    ASSERT(!test_bit(irq, d->pirq_mask) ||
+           (action->ack_type != ACKTYPE_NONE));
 
-    for ( pirq = find_first_bit(d->pirq_mask, NR_PIRQS);
-          pirq < NR_PIRQS;
-          pirq = find_next_bit(d->pirq_mask, NR_PIRQS, pirq+1) )
+    if ( unlikely(!test_and_clear_bit(irq, d->pirq_mask)) ||
+         unlikely(--action->in_flight != 0) )
     {
-        desc   = &irq_desc[irq_to_vector(pirq)];
-        action = (irq_guest_action_t *)desc->action;
+        spin_unlock_irq(&desc->lock);
+        return;
+    }
 
-        spin_lock_irq(&desc->lock);
+    if ( action->ack_type == ACKTYPE_UNMASK )
+    {
+        ASSERT(cpus_empty(action->cpu_eoi_map));
+        desc->handler->end(irq_to_vector(irq));
+        return;
+    }
 
-        if ( !test_bit(d->pirq_to_evtchn[pirq], s->evtchn_mask) &&
-             test_and_clear_bit(pirq, d->pirq_mask) )
-        {
-            ASSERT(action->ack_type != ACKTYPE_NONE);
-            if ( --action->in_flight == 0 )
-            {
-                if ( action->ack_type == ACKTYPE_UNMASK )
-                    desc->handler->end(irq_to_vector(pirq));
-                cpu_eoi_map = action->cpu_eoi_map;
-            }
-        }
+    ASSERT(action->ack_type == ACKTYPE_EOI);
+        
+    cpu_eoi_map = action->cpu_eoi_map;
 
-        if ( cpu_test_and_clear(cpu, cpu_eoi_map) )
-        {
-            __set_eoi_ready(desc);
-            spin_unlock(&desc->lock);
-            flush_ready_eoi(NULL);
-            local_irq_enable();
-        }
-        else
-        {
-            spin_unlock_irq(&desc->lock);
-        }
+    if ( cpu_test_and_clear(smp_processor_id(), cpu_eoi_map) )
+    {
+        __set_eoi_ready(desc);
+        spin_unlock(&desc->lock);
+        flush_ready_eoi(NULL);
+        local_irq_enable();
+    }
+    else
+    {
+        spin_unlock_irq(&desc->lock);
+    }
 
-        if ( !cpus_empty(cpu_eoi_map) )
-        {
-            on_selected_cpus(cpu_eoi_map, set_eoi_ready, desc, 1, 0);
-            cpu_eoi_map = CPU_MASK_NONE;
-        }
+    if ( !cpus_empty(cpu_eoi_map) )
+        on_selected_cpus(cpu_eoi_map, set_eoi_ready, desc, 1, 0);
+}
+
+int pirq_guest_eoi(struct domain *d, int irq)
+{
+    if ( (irq < 0) || (irq >= NR_IRQS) )
+        return -EINVAL;
+
+    __pirq_guest_eoi(d, irq);
+
+    return 0;
+}
+
+int pirq_guest_unmask(struct domain *d)
+{
+    unsigned int   irq;
+    shared_info_t *s = d->shared_info;
+
+    for ( irq = find_first_bit(d->pirq_mask, NR_PIRQS);
+          irq < NR_PIRQS;
+          irq = find_next_bit(d->pirq_mask, NR_PIRQS, irq+1) )
+    {
+        if ( !test_bit(d->pirq_to_evtchn[irq], s->evtchn_mask) )
+            __pirq_guest_eoi(d, irq);
     }
 
     return 0;
index 50155e1003c934e6d8119f6eeba2d0399055c4f1..48d259c85d9068d566988d030bef9b5a8811a1dc 100644 (file)
@@ -22,91 +22,123 @@ extern int
 pirq_acktype(
     int irq);
 
-/*
- * Demuxing hypercall.
- */
-long do_physdev_op(XEN_GUEST_HANDLE(physdev_op_t) uop)
+long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
 {
-    struct physdev_op op;
+    int irq;
     long ret;
-    int  irq;
-
-    if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
-        return -EFAULT;
 
-    switch ( op.cmd )
+    switch ( cmd )
     {
-    case PHYSDEVOP_IRQ_UNMASK_NOTIFY:
+    case PHYSDEVOP_eoi: {
+        struct physdev_eoi eoi;
+        ret = -EFAULT;
+        if ( copy_from_guest(&eoi, arg, 1) != 0 )
+            break;
+        ret = pirq_guest_eoi(current->domain, eoi.irq);
+        break;
+    }
+
+    /* Legacy since 0x00030202. */
+    case PHYSDEVOP_IRQ_UNMASK_NOTIFY: {
         ret = pirq_guest_unmask(current->domain);
         break;
+    }
 
-    case PHYSDEVOP_IRQ_STATUS_QUERY:
-        irq = op.u.irq_status_query.irq;
+    case PHYSDEVOP_irq_status_query: {
+        struct physdev_irq_status_query irq_status_query;
+        ret = -EFAULT;
+        if ( copy_from_guest(&irq_status_query, arg, 1) != 0 )
+            break;
+        irq = irq_status_query.irq;
         ret = -EINVAL;
         if ( (irq < 0) || (irq >= NR_IRQS) )
             break;
-        op.u.irq_status_query.flags = 0;
+        irq_status_query.flags = 0;
         if ( pirq_acktype(irq) != 0 )
-            op.u.irq_status_query.flags |= PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY;
-        ret = 0;
+            irq_status_query.flags |= XENIRQSTAT_needs_eoi;
+        ret = copy_to_guest(arg, &irq_status_query, 1) ? -EFAULT : 0;
         break;
+    }
 
-    case PHYSDEVOP_APIC_READ:
+    case PHYSDEVOP_apic_read: {
+        struct physdev_apic apic;
+        ret = -EFAULT;
+        if ( copy_from_guest(&apic, arg, 1) != 0 )
+            break;
         ret = -EPERM;
         if ( !IS_PRIV(current->domain) )
             break;
-        ret = ioapic_guest_read(
-            op.u.apic_op.apic_physbase,
-            op.u.apic_op.reg,
-            &op.u.apic_op.value);
+        ret = ioapic_guest_read(apic.apic_physbase, apic.reg, &apic.value);
+        if ( copy_to_guest(arg, &apic, 1) != 0 )
+            ret = -EFAULT;
         break;
+    }
 
-    case PHYSDEVOP_APIC_WRITE:
+    case PHYSDEVOP_apic_write: {
+        struct physdev_apic apic;
+        ret = -EFAULT;
+        if ( copy_from_guest(&apic, arg, 1) != 0 )
+            break;
         ret = -EPERM;
         if ( !IS_PRIV(current->domain) )
             break;
-        ret = ioapic_guest_write(
-            op.u.apic_op.apic_physbase,
-            op.u.apic_op.reg,
-            op.u.apic_op.value);
+        ret = ioapic_guest_write(apic.apic_physbase, apic.reg, apic.value);
         break;
+    }
 
-    case PHYSDEVOP_ASSIGN_VECTOR:
+    case PHYSDEVOP_alloc_irq_vector: {
+        struct physdev_irq irq_op;
+
+        ret = -EFAULT;
+        if ( copy_from_guest(&irq_op, arg, 1) != 0 )
+            break;
+
+        ret = -EPERM;
         if ( !IS_PRIV(current->domain) )
-            return -EPERM;
+            break;
 
-        if ( (irq = op.u.irq_op.irq) >= NR_IRQS )
-            return -EINVAL;
+        ret = -EINVAL;
+        if ( (irq = irq_op.irq) >= NR_IRQS )
+            break;
         
-        op.u.irq_op.vector = assign_irq_vector(irq);
-        ret = 0;
+        irq_op.vector = assign_irq_vector(irq);
+        ret = copy_to_guest(arg, &irq_op, 1) ? -EFAULT : 0;
         break;
+    }
 
-    case PHYSDEVOP_SET_IOPL:
+    case PHYSDEVOP_set_iopl: {
+        struct physdev_set_iopl set_iopl;
+        ret = -EFAULT;
+        if ( copy_from_guest(&set_iopl, arg, 1) != 0 )
+            break;
         ret = -EINVAL;
-        if ( op.u.set_iopl.iopl > 3 )
+        if ( set_iopl.iopl > 3 )
             break;
         ret = 0;
-        current->arch.iopl = op.u.set_iopl.iopl;
+        current->arch.iopl = set_iopl.iopl;
         break;
+    }
 
-    case PHYSDEVOP_SET_IOBITMAP:
+    case PHYSDEVOP_set_iobitmap: {
+        struct physdev_set_iobitmap set_iobitmap;
+        ret = -EFAULT;
+        if ( copy_from_guest(&set_iobitmap, arg, 1) != 0 )
+            break;
         ret = -EINVAL;
-        if ( !access_ok(op.u.set_iobitmap.bitmap, IOBMP_BYTES) ||
-             (op.u.set_iobitmap.nr_ports > 65536) )
+        if ( !access_ok(set_iobitmap.bitmap, IOBMP_BYTES) ||
+             (set_iobitmap.nr_ports > 65536) )
             break;
         ret = 0;
-        current->arch.iobmp       = op.u.set_iobitmap.bitmap;
-        current->arch.iobmp_limit = op.u.set_iobitmap.nr_ports;
+        current->arch.iobmp       = set_iobitmap.bitmap;
+        current->arch.iobmp_limit = set_iobitmap.nr_ports;
         break;
+    }
+
     default:
         ret = -EINVAL;
         break;
     }
 
-    if ( copy_to_guest(uop, &op, 1) )
-        ret = -EFAULT;
-
     return ret;
 }
 
index 1c1cf83901d3911c99ed694da6005542ab5322c4..1a4ac5367e204659a84f674c53627f9daf6f2140 100644 (file)
@@ -630,10 +630,10 @@ ENTRY(hypercall_table)
         .long do_multicall
         .long do_update_va_mapping
         .long do_set_timer_op       /* 15 */
-        .long do_event_channel_op
+        .long do_event_channel_op_compat
         .long do_xen_version
         .long do_console_io
-        .long do_physdev_op
+        .long do_physdev_op_compat
         .long do_grant_table_op     /* 20 */
         .long do_vm_assist
         .long do_update_va_mapping_otherdomain
@@ -646,6 +646,8 @@ ENTRY(hypercall_table)
         .long do_arch_sched_op
         .long do_callback_op        /* 30 */
         .long do_xenoprof_op
+        .long do_event_channel_op
+        .long do_physdev_op
         .rept NR_hypercalls-((.-hypercall_table)/4)
         .long do_ni_hypercall
         .endr
@@ -667,10 +669,10 @@ ENTRY(hypercall_args_table)
         .byte 2 /* do_multicall         */
         .byte 4 /* do_update_va_mapping */
         .byte 2 /* do_set_timer_op      */  /* 15 */
-        .byte 1 /* do_event_channel_op  */
+        .byte 1 /* do_event_channel_op_compat */
         .byte 2 /* do_xen_version       */
         .byte 3 /* do_console_io        */
-        .byte 1 /* do_physdev_op        */
+        .byte 1 /* do_physdev_op_compat */
         .byte 3 /* do_grant_table_op    */  /* 20 */
         .byte 2 /* do_vm_assist         */
         .byte 5 /* do_update_va_mapping_otherdomain */
@@ -683,6 +685,8 @@ ENTRY(hypercall_args_table)
         .byte 2 /* do_arch_sched_op     */
         .byte 2 /* do_callback_op       */  /* 30 */
         .byte 2 /* do_xenoprof_op       */
+        .byte 2 /* do_event_channel_op  */
+        .byte 2 /* do_physdev_op        */
         .rept NR_hypercalls-(.-hypercall_args_table)
         .byte 0 /* do_ni_hypercall      */
         .endr
index 9c27e2a5950bdcab246c01eac5d6fae8cdfce2c2..110c34a417150cc7057af4db0349d56392070dae 100644 (file)
@@ -538,10 +538,10 @@ ENTRY(hypercall_table)
         .quad do_multicall
         .quad do_update_va_mapping
         .quad do_set_timer_op       /* 15 */
-        .quad do_event_channel_op
+        .quad do_event_channel_op_compat
         .quad do_xen_version
         .quad do_console_io
-        .quad do_physdev_op
+        .quad do_physdev_op_compat
         .quad do_grant_table_op     /* 20 */
         .quad do_vm_assist
         .quad do_update_va_mapping_otherdomain
@@ -554,6 +554,8 @@ ENTRY(hypercall_table)
         .quad do_arch_sched_op
         .quad do_callback_op        /* 30 */
         .quad do_xenoprof_op
+        .quad do_event_channel_op
+        .quad do_physdev_op
         .rept NR_hypercalls-((.-hypercall_table)/8)
         .quad do_ni_hypercall
         .endr
@@ -575,10 +577,10 @@ ENTRY(hypercall_args_table)
         .byte 2 /* do_multicall         */
         .byte 3 /* do_update_va_mapping */
         .byte 1 /* do_set_timer_op      */  /* 15 */
-        .byte 1 /* do_event_channel_op  */
+        .byte 1 /* do_event_channel_op_compat */
         .byte 2 /* do_xen_version       */
         .byte 3 /* do_console_io        */
-        .byte 1 /* do_physdev_op        */
+        .byte 1 /* do_physdev_op_compat */
         .byte 3 /* do_grant_table_op    */  /* 20 */
         .byte 2 /* do_vm_assist         */
         .byte 4 /* do_update_va_mapping_otherdomain */
@@ -591,6 +593,8 @@ ENTRY(hypercall_args_table)
         .byte 2 /* do_arch_sched_op     */
         .byte 2 /* do_callback_op       */  /* 30 */
         .byte 2 /* do_xenoprof_op       */
+        .byte 2 /* do_event_channel_op  */
+        .byte 2 /* do_physdev_op        */
         .rept NR_hypercalls-(.-hypercall_args_table)
         .byte 0 /* do_ni_hypercall      */
         .endr
index 1bfd792b3b3a7bd3f498d195a9a9dc04877c7783..c02ef9ac082e570e4253d1b84fb50649c8b4239a 100644 (file)
@@ -97,7 +97,10 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
     struct domain *d;
     int            port;
     domid_t        dom = alloc->dom;
-    long           rc = 0;
+    long           rc;
+
+    if ( (rc = acm_pre_eventchannel_unbound(dom, alloc->remote_dom)) != 0 )
+        return rc;
 
     if ( dom == DOMID_SELF )
         dom = current->domain->domain_id;
@@ -134,7 +137,10 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
     struct domain *ld = current->domain, *rd;
     int            lport, rport = bind->remote_port;
     domid_t        rdom = bind->remote_dom;
-    long           rc = 0;
+    long           rc;
+
+    if ( (rc = acm_pre_eventchannel_interdomain(rdom)) != 0 )
+        return rc;
 
     if ( rdom == DOMID_SELF )
         rdom = current->domain->domain_id;
@@ -201,13 +207,14 @@ static long evtchn_bind_virq(evtchn_bind_virq_t *bind)
     int            port, virq = bind->virq, vcpu = bind->vcpu;
     long           rc = 0;
 
-    if ( virq >= ARRAY_SIZE(v->virq_to_evtchn) )
+    if ( (virq < 0) || (virq >= ARRAY_SIZE(v->virq_to_evtchn)) )
         return -EINVAL;
 
     if ( virq_is_global(virq) && (vcpu != 0) )
         return -EINVAL;
 
-    if ( (vcpu >= ARRAY_SIZE(d->vcpu)) || ((v = d->vcpu[vcpu]) == NULL) )
+    if ( (vcpu < 0) || (vcpu >= ARRAY_SIZE(d->vcpu)) ||
+         ((v = d->vcpu[vcpu]) == NULL) )
         return -ENOENT;
 
     spin_lock(&d->evtchn_lock);
@@ -239,7 +246,8 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
     int            port, vcpu = bind->vcpu;
     long           rc = 0;
 
-    if ( (vcpu >= ARRAY_SIZE(d->vcpu)) || (d->vcpu[vcpu] == NULL) )
+    if ( (vcpu < 0) || (vcpu >= ARRAY_SIZE(d->vcpu)) ||
+         (d->vcpu[vcpu] == NULL) )
         return -ENOENT;
 
     spin_lock(&d->evtchn_lock);
@@ -267,7 +275,7 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
     int            port, pirq = bind->pirq;
     long           rc;
 
-    if ( pirq >= ARRAY_SIZE(d->pirq_to_evtchn) )
+    if ( (pirq < 0) || (pirq >= ARRAY_SIZE(d->pirq_to_evtchn)) )
         return -EINVAL;
 
     if ( !irq_access_permitted(d, pirq) )
@@ -683,70 +691,103 @@ static long evtchn_unmask(evtchn_unmask_t *unmask)
 }
 
 
-long do_event_channel_op(XEN_GUEST_HANDLE(evtchn_op_t) uop)
+long do_event_channel_op(int cmd, XEN_GUEST_HANDLE(void) arg)
 {
     long rc;
-    struct evtchn_op op;
-
-    if ( copy_from_guest(&op, uop, 1) != 0 )
-        return -EFAULT;
 
-    if (acm_pre_event_channel(&op))
-        return -EACCES;
-
-    switch ( op.cmd )
+    switch ( cmd )
     {
-    case EVTCHNOP_alloc_unbound:
-        rc = evtchn_alloc_unbound(&op.u.alloc_unbound);
-        if ( (rc == 0) && (copy_to_guest(uop, &op, 1) != 0) )
+    case EVTCHNOP_alloc_unbound: {
+        struct evtchn_alloc_unbound alloc_unbound;
+        if ( copy_from_guest(&alloc_unbound, arg, 1) != 0 )
+            return -EFAULT;
+        rc = evtchn_alloc_unbound(&alloc_unbound);
+        if ( (rc == 0) && (copy_to_guest(arg, &alloc_unbound, 1) != 0) )
             rc = -EFAULT; /* Cleaning up here would be a mess! */
         break;
+    }
 
-    case EVTCHNOP_bind_interdomain:
-        rc = evtchn_bind_interdomain(&op.u.bind_interdomain);
-        if ( (rc == 0) && (copy_to_guest(uop, &op, 1) != 0) )
+    case EVTCHNOP_bind_interdomain: {
+        struct evtchn_bind_interdomain bind_interdomain;
+        if ( copy_from_guest(&bind_interdomain, arg, 1) != 0 )
+            return -EFAULT;
+        rc = evtchn_bind_interdomain(&bind_interdomain);
+        if ( (rc == 0) && (copy_to_guest(arg, &bind_interdomain, 1) != 0) )
             rc = -EFAULT; /* Cleaning up here would be a mess! */
         break;
+    }
 
-    case EVTCHNOP_bind_virq:
-        rc = evtchn_bind_virq(&op.u.bind_virq);
-        if ( (rc == 0) && (copy_to_guest(uop, &op, 1) != 0) )
+    case EVTCHNOP_bind_virq: {
+        struct evtchn_bind_virq bind_virq;
+        if ( copy_from_guest(&bind_virq, arg, 1) != 0 )
+            return -EFAULT;
+        rc = evtchn_bind_virq(&bind_virq);
+        if ( (rc == 0) && (copy_to_guest(arg, &bind_virq, 1) != 0) )
             rc = -EFAULT; /* Cleaning up here would be a mess! */
         break;
+    }
 
-    case EVTCHNOP_bind_ipi:
-        rc = evtchn_bind_ipi(&op.u.bind_ipi);
-        if ( (rc == 0) && (copy_to_guest(uop, &op, 1) != 0) )
+    case EVTCHNOP_bind_ipi: {
+        struct evtchn_bind_ipi bind_ipi;
+        if ( copy_from_guest(&bind_ipi, arg, 1) != 0 )
+            return -EFAULT;
+        rc = evtchn_bind_ipi(&bind_ipi);
+        if ( (rc == 0) && (copy_to_guest(arg, &bind_ipi, 1) != 0) )
             rc = -EFAULT; /* Cleaning up here would be a mess! */
         break;
+    }
 
-    case EVTCHNOP_bind_pirq:
-        rc = evtchn_bind_pirq(&op.u.bind_pirq);
-        if ( (rc == 0) && (copy_to_guest(uop, &op, 1) != 0) )
+    case EVTCHNOP_bind_pirq: {
+        struct evtchn_bind_pirq bind_pirq;
+        if ( copy_from_guest(&bind_pirq, arg, 1) != 0 )
+            return -EFAULT;
+        rc = evtchn_bind_pirq(&bind_pirq);
+        if ( (rc == 0) && (copy_to_guest(arg, &bind_pirq, 1) != 0) )
             rc = -EFAULT; /* Cleaning up here would be a mess! */
         break;
+    }
 
-    case EVTCHNOP_close:
-        rc = evtchn_close(&op.u.close);
+    case EVTCHNOP_close: {
+        struct evtchn_close close;
+        if ( copy_from_guest(&close, arg, 1) != 0 )
+            return -EFAULT;
+        rc = evtchn_close(&close);
         break;
+    }
 
-    case EVTCHNOP_send:
-        rc = evtchn_send(op.u.send.port);
+    case EVTCHNOP_send: {
+        struct evtchn_send send;
+        if ( copy_from_guest(&send, arg, 1) != 0 )
+            return -EFAULT;
+        rc = evtchn_send(send.port);
         break;
+    }
 
-    case EVTCHNOP_status:
-        rc = evtchn_status(&op.u.status);
-        if ( (rc == 0) && (copy_to_guest(uop, &op, 1) != 0) )
+    case EVTCHNOP_status: {
+        struct evtchn_status status;
+        if ( copy_from_guest(&status, arg, 1) != 0 )
+            return -EFAULT;
+        rc = evtchn_status(&status);
+        if ( (rc == 0) && (copy_to_guest(arg, &status, 1) != 0) )
             rc = -EFAULT;
         break;
+    }
 
-    case EVTCHNOP_bind_vcpu:
-        rc = evtchn_bind_vcpu(op.u.bind_vcpu.port, op.u.bind_vcpu.vcpu);
+    case EVTCHNOP_bind_vcpu: {
+        struct evtchn_bind_vcpu bind_vcpu;
+        if ( copy_from_guest(&bind_vcpu, arg, 1) != 0 )
+            return -EFAULT;
+        rc = evtchn_bind_vcpu(bind_vcpu.port, bind_vcpu.vcpu);
         break;
+    }
 
-    case EVTCHNOP_unmask:
-        rc = evtchn_unmask(&op.u.unmask);
+    case EVTCHNOP_unmask: {
+        struct evtchn_unmask unmask;
+        if ( copy_from_guest(&unmask, arg, 1) != 0 )
+            return -EFAULT;
+        rc = evtchn_unmask(&unmask);
         break;
+    }
 
     default:
         rc = -ENOSYS;
index a48755e9f18c81777950599f453206d080a72acb..c89eca7c73939c9f5fda1009376491e9b2d6f22f 100644 (file)
@@ -135,7 +135,9 @@ static inline void acm_post_dom0_op(struct dom0_op *op, void *ssid)
 { return; }
 static inline void acm_fail_dom0_op(struct dom0_op *op, void *ssid) 
 { return; }
-static inline int acm_pre_event_channel(struct evtchn_op *op) 
+static inline int acm_pre_eventchannel_unbound(domid_t id1, domid_t id2)
+{ return 0; }
+static inline int acm_pre_eventchannel_interdomain(domid_t id)
 { return 0; }
 static inline int acm_pre_grant_map_ref(domid_t id) 
 { return 0; }
@@ -289,26 +291,6 @@ static inline void acm_fail_dom0_op(struct dom0_op *op, void *ssid)
     }
 }
 
-static inline int acm_pre_event_channel(struct evtchn_op *op) 
-{
-    int ret = -EACCES;
-
-    switch(op->cmd) {
-    case EVTCHNOP_alloc_unbound:
-        ret = acm_pre_eventchannel_unbound(
-                  op->u.alloc_unbound.dom,
-                  op->u.alloc_unbound.remote_dom);
-        break;
-    case EVTCHNOP_bind_interdomain:
-        ret = acm_pre_eventchannel_interdomain(
-                  op->u.bind_interdomain.remote_dom);
-        break;
-    default:
-        ret = 0; /* ok */
-    }
-    return ret;
-}
-
 static inline int acm_pre_grant_map_ref(domid_t id)
 {
     if ( (acm_primary_ops->pre_grant_map_ref != NULL) &&
index ad34db37d88fd119dd21a243f040b8b23d8e6889..6e4a0320fd93956118a51d18aff5fb97e335bd03 100644 (file)
@@ -9,6 +9,10 @@
 #include <asm/types.h>
 #include <asm/vcpu.h>
 
+extern long
+do_event_channel_op_compat(
+    XEN_GUEST_HANDLE(evtchn_op_t) uop);
+
 extern int
 vmx_do_mmu_update(
     mmu_update_t *ureqs,
index e324e693d60965dd2e67ab772e02318a5b826151..69d7ba793d5e23b09c72f89e4b59456fca6fc5e4 100644 (file)
@@ -7,6 +7,14 @@
 
 #include <public/physdev.h>
 
+extern long
+do_event_channel_op_compat(
+    XEN_GUEST_HANDLE(evtchn_op_t) uop);
+
+extern long
+do_physdev_op_compat(
+    XEN_GUEST_HANDLE(physdev_op_t) uop);
+
 extern long
 do_set_trap_table(
     XEN_GUEST_HANDLE(trap_info_t) traps);
@@ -54,7 +62,7 @@ do_update_va_mapping(
 
 extern long
 do_physdev_op(
-    XEN_GUEST_HANDLE(physdev_op_t) uop);
+    int cmd, XEN_GUEST_HANDLE(void) arg);
 
 extern int
 do_update_va_mapping_otherdomain(
index d79a4bc8614366c256d0919956ac22b53da425d3..24de4201548a31dc735fbdec864807b3555a400d 100644 (file)
@@ -9,6 +9,13 @@
 #ifndef __XEN_PUBLIC_EVENT_CHANNEL_H__
 #define __XEN_PUBLIC_EVENT_CHANNEL_H__
 
+/*
+ * Prototype for this hypercall is:
+ *  int event_channel_op(int cmd, void *args)
+ * @cmd  == EVTCHNOP_??? (event-channel operation).
+ * @args == Operation-specific extra arguments (NULL if none).
+ */
+
 typedef uint32_t evtchn_port_t;
 DEFINE_XEN_GUEST_HANDLE(evtchn_port_t);
 
@@ -181,6 +188,10 @@ typedef struct evtchn_unmask {
     evtchn_port_t port;
 } evtchn_unmask_t;
 
+/*
+ * Argument to event_channel_op_compat() hypercall. Superceded by new
+ * event_channel_op() hypercall since 0x00030202.
+ */
 typedef struct evtchn_op {
     uint32_t cmd; /* EVTCHNOP_* */
     union {
index e12fafe9188096d43085477ce126ee3b02cfeb01..ccb6f87a0b7e18f25b0e90de6c42eaf2f4a7a29b 100644 (file)
 #ifndef __XEN_PUBLIC_PHYSDEV_H__
 #define __XEN_PUBLIC_PHYSDEV_H__
 
-/* Commands to HYPERVISOR_physdev_op() */
-#define PHYSDEVOP_IRQ_UNMASK_NOTIFY     4
-#define PHYSDEVOP_IRQ_STATUS_QUERY      5
-#define PHYSDEVOP_SET_IOPL              6
-#define PHYSDEVOP_SET_IOBITMAP          7
-#define PHYSDEVOP_APIC_READ             8
-#define PHYSDEVOP_APIC_WRITE            9
-#define PHYSDEVOP_ASSIGN_VECTOR         10
+/*
+ * Prototype for this hypercall is:
+ *  int physdev_op(int cmd, void *args)
+ * @cmd  == PHYSDEVOP_??? (physdev operation).
+ * @args == Operation-specific extra arguments (NULL if none).
+ */
+
+/*
+ * Notify end-of-interrupt (EOI) for the specified IRQ.
+ * @arg == pointer to physdev_eoi structure.
+ */
+#define PHYSDEVOP_eoi                   12
+typedef struct physdev_eoi {
+    /* IN */
+    uint32_t irq;
+} physdev_eoi_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t);
 
-typedef struct physdevop_irq_status_query {
+/*
+ * Query the status of an IRQ line.
+ * @arg == pointer to physdev_irq_status_query structure.
+ */
+#define PHYSDEVOP_irq_status_query       5
+typedef struct physdev_irq_status_query {
     /* IN */
     uint32_t irq;
     /* OUT */
-/* Need to call PHYSDEVOP_IRQ_UNMASK_NOTIFY when the IRQ has been serviced? */
-#define PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY (1<<0)
-    uint32_t flags;
-} physdevop_irq_status_query_t;
+    uint32_t flags; /* XENIRQSTAT_* */
+} physdev_irq_status_query_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_irq_status_query_t);
 
-typedef struct physdevop_set_iopl {
+/* Need to call PHYSDEVOP_eoi when the IRQ has been serviced? */
+#define _XENIRQSTAT_needs_eoi   (0)
+#define  XENIRQSTAT_needs_eoi   (1<<_XENIRQSTAT_needs_eoi)
+
+/*
+ * Set the current VCPU's I/O privilege level.
+ * @arg == pointer to physdev_set_iopl structure.
+ */
+#define PHYSDEVOP_set_iopl               6
+typedef struct physdev_set_iopl {
     /* IN */
     uint32_t iopl;
-} physdevop_set_iopl_t;
+} physdev_set_iopl_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_set_iopl_t);
 
-typedef struct physdevop_set_iobitmap {
+/*
+ * Set the current VCPU's I/O-port permissions bitmap.
+ * @arg == pointer to physdev_set_iobitmap structure.
+ */
+#define PHYSDEVOP_set_iobitmap           7
+typedef struct physdev_set_iobitmap {
     /* IN */
     uint8_t *bitmap;
     uint32_t nr_ports;
-} physdevop_set_iobitmap_t;
+} physdev_set_iobitmap_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_set_iobitmap_t);
 
-typedef struct physdevop_apic {
+/*
+ * Read or write an IO-APIC register.
+ * @arg == pointer to physdev_apic structure.
+ */
+#define PHYSDEVOP_apic_read              8
+#define PHYSDEVOP_apic_write             9
+typedef struct physdev_apic {
     /* IN */
     unsigned long apic_physbase;
     uint32_t reg;
     /* IN or OUT */
     uint32_t value;
-} physdevop_apic_t;
+} physdev_apic_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_apic_t);
 
-typedef struct physdevop_irq {
+/*
+ * Allocate or free a physical upcall vector for the specified IRQ line.
+ * @arg == pointer to physdev_irq structure.
+ */
+#define PHYSDEVOP_alloc_irq_vector      10
+#define PHYSDEVOP_free_irq_vector       11
+typedef struct physdev_irq {
     /* IN */
     uint32_t irq;
-    /* OUT */
+    /* IN or OUT */
     uint32_t vector;
-} physdevop_irq_t;
+} physdev_irq_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_irq_t);
 
+/*
+ * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op()
+ * hypercall since 0x00030202.
+ */
 typedef struct physdev_op {
     uint32_t cmd;
     union {
-        physdevop_irq_status_query_t      irq_status_query;
-        physdevop_set_iopl_t              set_iopl;
-        physdevop_set_iobitmap_t          set_iobitmap;
-        physdevop_apic_t                  apic_op;
-        physdevop_irq_t                   irq_op;
+        physdev_irq_status_query_t      irq_status_query;
+        physdev_set_iopl_t              set_iopl;
+        physdev_set_iobitmap_t          set_iobitmap;
+        physdev_apic_t                  apic_op;
+        physdev_irq_t                   irq_op;
     } u;
 } physdev_op_t;
 DEFINE_XEN_GUEST_HANDLE(physdev_op_t);
 
+/*
+ * Notify that some PIRQ-bound event channels have been unmasked.
+ * ** This command is obsolete since interface version 0x00030202 and is **
+ * ** unsupported by newer versions of Xen.                              **
+ */
+#define PHYSDEVOP_IRQ_UNMASK_NOTIFY      4
+
+/*
+ * These all-capitals physdev operation names are superceded by the new names
+ * (defined above) since interface version 0x00030202.
+ */
+#define PHYSDEVOP_IRQ_STATUS_QUERY       PHYSDEVOP_irq_status_query
+#define PHYSDEVOP_SET_IOPL               PHYSDEVOP_set_iopl
+#define PHYSDEVOP_SET_IOBITMAP           PHYSDEVOP_set_iobitmap
+#define PHYSDEVOP_APIC_READ              PHYSDEVOP_apic_read
+#define PHYSDEVOP_APIC_WRITE             PHYSDEVOP_apic_write
+#define PHYSDEVOP_ASSIGN_VECTOR          PHYSDEVOP_alloc_irq_vector
+#define PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY XENIRQSTAT_needs_eoi
+
 #endif /* __XEN_PUBLIC_PHYSDEV_H__ */
 
 /*
index ffea28d520af8c79f7bb49f7efbbd0371f14a118..65cd7443fdf718c64e850c0ac766d71fd199705e 100644 (file)
@@ -9,7 +9,7 @@
 #ifndef __XEN_PUBLIC_XEN_COMPAT_H__
 #define __XEN_PUBLIC_XEN_COMPAT_H__
 
-#define __XEN_LATEST_INTERFACE_VERSION__ 0x00030201
+#define __XEN_LATEST_INTERFACE_VERSION__ 0x00030202
 
 #if defined(__XEN__) || defined(__XEN_TOOLS__)
 /* Xen is built with matching headers and implements the latest interface. */
     typedef type * __guest_handle_ ## name
 #endif
 
+/* New event-channel and physdev hypercalls introduced in 0x00030202. */
+#if __XEN_INTERFACE_VERSION__ < 0x00030202
+#undef __HYPERVISOR_event_channel_op
+#define __HYPERVISOR_event_channel_op __HYPERVISOR_event_channel_op_compat
+#undef __HYPERVISOR_physdev_op
+#define __HYPERVISOR_physdev_op __HYPERVISOR_physdev_op_compat
+#endif
+
 #endif /* __XEN_PUBLIC_XEN_COMPAT_H__ */
index a481df3440c794806ecf93d69ab54ba892f959dd..75fbcba20c80474302cef406436771c9b373d450 100644 (file)
@@ -37,7 +37,7 @@
 #define __HYPERVISOR_stack_switch          3
 #define __HYPERVISOR_set_callbacks         4
 #define __HYPERVISOR_fpu_taskswitch        5
-#define __HYPERVISOR_sched_op_compat       6 /* compat as of 0x00030101 */
+#define __HYPERVISOR_sched_op_compat       6 /* compat since 0x00030101 */
 #define __HYPERVISOR_dom0_op               7
 #define __HYPERVISOR_set_debugreg          8
 #define __HYPERVISOR_get_debugreg          9
 #define __HYPERVISOR_multicall            13
 #define __HYPERVISOR_update_va_mapping    14
 #define __HYPERVISOR_set_timer_op         15
-#define __HYPERVISOR_event_channel_op     16
+#define __HYPERVISOR_event_channel_op_compat 16 /* compat since 0x00030202 */
 #define __HYPERVISOR_xen_version          17
 #define __HYPERVISOR_console_io           18
-#define __HYPERVISOR_physdev_op           19
+#define __HYPERVISOR_physdev_op_compat    19 /* compat since 0x00030202 */
 #define __HYPERVISOR_grant_table_op       20
 #define __HYPERVISOR_vm_assist            21
 #define __HYPERVISOR_update_va_mapping_otherdomain 22
@@ -62,6 +62,8 @@
 #define __HYPERVISOR_sched_op             29
 #define __HYPERVISOR_callback_op          30
 #define __HYPERVISOR_xenoprof_op          31
+#define __HYPERVISOR_event_channel_op     32
+#define __HYPERVISOR_physdev_op           33
 
 /* Architecture-specific hypercall definitions. */
 #define __HYPERVISOR_arch_0               48
index b894dd1beb8082185428d04f4c8296a4799d6a9d..fcdfba46a685cb075836eb79738105c38505ca7f 100644 (file)
@@ -9,6 +9,7 @@
 #include <xen/types.h>
 #include <xen/time.h>
 #include <public/xen.h>
+#include <public/dom0_ops.h>
 #include <public/acm_ops.h>
 #include <public/event_channel.h>
 #include <asm/hypercall.h>
@@ -47,7 +48,7 @@ do_set_timer_op(
 
 extern long
 do_event_channel_op(
-    XEN_GUEST_HANDLE(evtchn_op_t) uop);
+    int cmd, XEN_GUEST_HANDLE(void) arg);
 
 extern long
 do_xen_version(
index 7b1f826198d50e0eb068281bfde9bf191bac8c57..b3f8f9d548c2f6d3466ea07efaaa1458b57790f1 100644 (file)
@@ -68,8 +68,9 @@ extern void no_action(int cpl, void *dev_id, struct cpu_user_regs *regs);
 
 struct domain;
 struct vcpu;
-extern int pirq_guest_unmask(struct domain *p);
-extern int pirq_guest_bind(struct vcpu *p, int irq, int will_share);
-extern int pirq_guest_unbind(struct domain *p, int irq);
+extern int pirq_guest_eoi(struct domain *d, int irq);
+extern int pirq_guest_unmask(struct domain *d);
+extern int pirq_guest_bind(struct vcpu *v, int irq, int will_share);
+extern int pirq_guest_unbind(struct domain *d, int irq);
 
 #endif /* __XEN_IRQ_H__ */